diff --git a/BUILD.gn b/BUILD.gn
index a14dc64..d16075d6 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -71,6 +71,7 @@
     "//base:base_unittests",
     "//chrome/installer",
     "//net:net_unittests",
+    "//skia:skia_unittests",
     "//sql:sql_unittests",
     "//tools/ipc_fuzzer:ipc_fuzzer_all",
     "//url:url_unittests",
@@ -88,7 +89,6 @@
       "//components:components_unittests",
       "//services:services_unittests",
       "//services/service_manager/public/cpp",
-      "//skia:skia_unittests",
       "//tools/metrics:metrics_metadata",
       "//ui/base:ui_base_unittests",
       "//ui/gfx:gfx_unittests",
@@ -162,6 +162,7 @@
       "//chrome/test:unit_tests",
       "//components:components_browsertests",
       "//components/policy:policy_templates",
+      "//components/viz:viz_perftests",
       "//components/viz:viz_unittests",
       "//components/viz/common:viz_benchmark",
       "//content/shell:content_shell",
diff --git a/DEPS b/DEPS
index 735f292..24ae794 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': 'c4176a2fa5aab30e5886f05bbe20de225dbe997b',
+  'skia_revision': '1c8bb8a4c63c327fb856a41e1b0b19775eac0ac1',
   # 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': '8b00387af39d3b35326c4510f1f7e213fbd56a5d',
+  'v8_revision': 'a51d9227579537d6859851ecdc72d643c97f12ef',
   # 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': '3d2d34dde457f07ca410d1c06f4f3b9063c28643',
+  'buildtools_revision': '1dcd1bdbe93467531a50b60dbd18860803ca7be1',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # 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': '08d8c9f0860202115b653dc31a06d366a5978623',
+  'catapult_revision': '6c40c273a7fe857803a56575644cfa81880673ad',
   # 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/PRESUBMIT.py b/PRESUBMIT.py
index 3ab7802..8cb86fe 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -204,12 +204,11 @@
       'ScopedAllowIO',
       (
        'New production code should not use ScopedAllowIO (using it in',
-       'browser tests is fine). Post a task to the blocking pool or the',
-       'FILE thread instead.',
+       'tests is fine). Post a task to a MayBlock task runner instead.',
       ),
       True,
       (
-        r"^.*browser(|_)test[a-z_]*\.cc$",
+        r"^.*(browser|unit)(|_)test[a-z_]*\.cc$",
         r"^base[\\\/]memory[\\\/]shared_memory_posix\.cc$",
         r"^base[\\\/]process[\\\/]internal_aix\.cc$",
         r"^base[\\\/]process[\\\/]process_linux\.cc$",
diff --git a/android_webview/BUILD.gn b/android_webview/BUILD.gn
index 3b7fc37b8..a63bd08 100644
--- a/android_webview/BUILD.gn
+++ b/android_webview/BUILD.gn
@@ -724,6 +724,7 @@
     "//components/version_info",
     "//components/visitedlink/browser",
     "//components/visitedlink/renderer",
+    "//components/viz/service",
     "//components/web_contents_delegate_android:web_contents_delegate_android",
     "//components/web_restrictions:browser",
     "//content",
diff --git a/android_webview/browser/DEPS b/android_webview/browser/DEPS
index 6c8f9675..8a8b7b4 100644
--- a/android_webview/browser/DEPS
+++ b/android_webview/browser/DEPS
@@ -30,6 +30,8 @@
   "+components/user_prefs",
   "+components/visitedlink/browser",
   "+components/viz/common",
+  "+components/viz/service/display",
+  "+components/viz/service/frame_sinks",
   "+components/webdata/common",
 
   "+content/public/browser",
diff --git a/android_webview/browser/aw_browser_main_parts.cc b/android_webview/browser/aw_browser_main_parts.cc
index 4856e17..4d09fd4 100644
--- a/android_webview/browser/aw_browser_main_parts.cc
+++ b/android_webview/browser/aw_browser_main_parts.cc
@@ -167,6 +167,9 @@
       new AwGeolocationDelegate());
 
   content::RenderFrameHost::AllowInjectingJavaScriptForAndroidWebView();
+
+  // TODO(meacer): Remove when PlzNavigate ships.
+  content::RenderFrameHost::AllowDataUrlNavigationForAndroidWebView();
 }
 
 bool AwBrowserMainParts::MainMessageLoopRun(int* result_code) {
diff --git a/android_webview/browser/hardware_renderer.cc b/android_webview/browser/hardware_renderer.cc
index b82665f..dc11300 100644
--- a/android_webview/browser/hardware_renderer.cc
+++ b/android_webview/browser/hardware_renderer.cc
@@ -15,9 +15,9 @@
 #include "base/memory/ptr_util.h"
 #include "base/trace_event/trace_event.h"
 #include "cc/output/compositor_frame.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
 #include "cc/surfaces/frame_sink_manager.h"
 #include "components/viz/common/local_surface_id_allocator.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "ui/gfx/transform.h"
 #include "ui/gl/gl_bindings.h"
 
@@ -262,7 +262,7 @@
   constexpr bool handles_frame_sink_id_invalidation = false;
   constexpr bool needs_sync_points = true;
   support_.reset();
-  support_ = cc::CompositorFrameSinkSupport::Create(
+  support_ = viz::CompositorFrameSinkSupport::Create(
       this, surfaces_->GetFrameSinkManager(), frame_sink_id_, is_root,
       handles_frame_sink_id_invalidation, needs_sync_points);
 }
diff --git a/android_webview/browser/hardware_renderer.h b/android_webview/browser/hardware_renderer.h
index 7099f1b2..d849cd03 100644
--- a/android_webview/browser/hardware_renderer.h
+++ b/android_webview/browser/hardware_renderer.h
@@ -11,17 +11,14 @@
 #include "android_webview/browser/compositor_id.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
 #include "components/viz/common/frame_sink_id.h"
 #include "components/viz/common/surface_id.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h"
 
 struct AwDrawGLInfo;
 
-namespace cc {
-class CompositorFrameSinkSupport;
-}
-
 namespace viz {
+class CompositorFrameSinkSupport;
 class LocalSurfaceIdAllocator;
 }
 
@@ -31,7 +28,7 @@
 class RenderThreadManager;
 class SurfacesInstance;
 
-class HardwareRenderer : public cc::CompositorFrameSinkSupportClient {
+class HardwareRenderer : public viz::CompositorFrameSinkSupportClient {
  public:
   // Two rules:
   // 1) Never wait on |new_frame| on the UI thread, or in kModeSync. Otherwise
@@ -52,7 +49,7 @@
   void CommitFrame();
 
  private:
-  // cc::CompositorFrameSinkSupportClient implementation.
+  // viz::CompositorFrameSinkSupportClient implementation.
   void DidReceiveCompositorFrameAck(
       const std::vector<cc::ReturnedResource>& resources) override;
   void OnBeginFrame(const cc::BeginFrameArgs& args) override;
@@ -95,7 +92,7 @@
   viz::FrameSinkId frame_sink_id_;
   const std::unique_ptr<viz::LocalSurfaceIdAllocator>
       local_surface_id_allocator_;
-  std::unique_ptr<cc::CompositorFrameSinkSupport> support_;
+  std::unique_ptr<viz::CompositorFrameSinkSupport> support_;
   viz::LocalSurfaceId child_id_;
   CompositorID compositor_id_;
   // HardwareRenderer guarantees resources are returned in the order of
diff --git a/android_webview/browser/surfaces_instance.cc b/android_webview/browser/surfaces_instance.cc
index 3064b23..42cc6ce8 100644
--- a/android_webview/browser/surfaces_instance.cc
+++ b/android_webview/browser/surfaces_instance.cc
@@ -17,11 +17,11 @@
 #include "cc/quads/solid_color_draw_quad.h"
 #include "cc/quads/surface_draw_quad.h"
 #include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
-#include "cc/surfaces/display.h"
-#include "cc/surfaces/display_scheduler.h"
 #include "cc/surfaces/frame_sink_manager.h"
 #include "components/viz/common/local_surface_id_allocator.h"
+#include "components/viz/service/display/display.h"
+#include "components/viz/service/display/display_scheduler.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/gfx/transform.h"
@@ -60,7 +60,7 @@
   constexpr bool is_root = true;
   constexpr bool handles_frame_sink_id_invalidation = true;
   constexpr bool needs_sync_points = true;
-  support_ = cc::CompositorFrameSinkSupport::Create(
+  support_ = viz::CompositorFrameSinkSupport::Create(
       this, frame_sink_manager_.get(), frame_sink_id_, is_root,
       handles_frame_sink_id_invalidation, needs_sync_points);
 
@@ -72,14 +72,14 @@
           make_scoped_refptr(new AwGLSurface),
           DeferredGpuCommandService::GetInstance())));
   output_surface_ = output_surface_holder.get();
-  std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler(
+  auto scheduler = base::MakeUnique<viz::DisplayScheduler>(
       begin_frame_source_.get(), nullptr,
-      output_surface_holder->capabilities().max_frames_pending));
-  display_.reset(new cc::Display(
+      output_surface_holder->capabilities().max_frames_pending);
+  display_ = base::MakeUnique<viz::Display>(
       nullptr /* shared_bitmap_manager */,
       nullptr /* gpu_memory_buffer_manager */, settings, frame_sink_id_,
       std::move(output_surface_holder), std::move(scheduler),
-      std::move(texture_mailbox_deleter)));
+      std::move(texture_mailbox_deleter));
   display_->Initialize(this, frame_sink_manager_->surface_manager());
   frame_sink_manager_->RegisterBeginFrameSource(begin_frame_source_.get(),
                                                 frame_sink_id_);
diff --git a/android_webview/browser/surfaces_instance.h b/android_webview/browser/surfaces_instance.h
index 7fd8ce2..24d49f63 100644
--- a/android_webview/browser/surfaces_instance.h
+++ b/android_webview/browser/surfaces_instance.h
@@ -9,16 +9,14 @@
 #include <vector>
 
 #include "base/memory/ref_counted.h"
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
-#include "cc/surfaces/display_client.h"
 #include "components/viz/common/frame_sink_id.h"
 #include "components/viz/common/frame_sink_id_allocator.h"
 #include "components/viz/common/surface_id.h"
+#include "components/viz/service/display/display_client.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h"
 
 namespace cc {
 class BeginFrameSource;
-class CompositorFrameSinkSupport;
-class Display;
 class FrameSinkManager;
 }
 
@@ -29,16 +27,18 @@
 }
 
 namespace viz {
+class CompositorFrameSinkSupport;
+class Display;
 class LocalSurfaceIdAllocator;
-}
+}  // namespace viz
 
 namespace android_webview {
 
 class ParentOutputSurface;
 
 class SurfacesInstance : public base::RefCounted<SurfacesInstance>,
-                         public cc::DisplayClient,
-                         public cc::CompositorFrameSinkSupportClient {
+                         public viz::DisplayClient,
+                         public viz::CompositorFrameSinkSupportClient {
  public:
   static scoped_refptr<SurfacesInstance> GetOrCreateInstance();
 
@@ -60,14 +60,14 @@
   SurfacesInstance();
   ~SurfacesInstance() override;
 
-  // cc::DisplayClient overrides.
+  // viz::DisplayClient overrides.
   void DisplayOutputSurfaceLost() override;
   void DisplayWillDrawAndSwap(
       bool will_draw_and_swap,
       const cc::RenderPassList& render_passes) override {}
   void DisplayDidDrawAndSwap() override {}
 
-  // cc::CompositorFrameSinkSupportClient implementation.
+  // viz::CompositorFrameSinkSupportClient implementation.
   void DidReceiveCompositorFrameAck(
       const std::vector<cc::ReturnedResource>& resources) override;
   void OnBeginFrame(const cc::BeginFrameArgs& args) override;
@@ -84,9 +84,9 @@
 
   std::unique_ptr<cc::FrameSinkManager> frame_sink_manager_;
   std::unique_ptr<cc::BeginFrameSource> begin_frame_source_;
-  std::unique_ptr<cc::Display> display_;
+  std::unique_ptr<viz::Display> display_;
   std::unique_ptr<viz::LocalSurfaceIdAllocator> local_surface_id_allocator_;
-  std::unique_ptr<cc::CompositorFrameSinkSupport> support_;
+  std::unique_ptr<viz::CompositorFrameSinkSupport> support_;
 
   viz::LocalSurfaceId root_id_;
   std::vector<viz::SurfaceId> child_ids_;
diff --git a/android_webview/glue/BUILD.gn b/android_webview/glue/BUILD.gn
index b114738..d2218ec 100644
--- a/android_webview/glue/BUILD.gn
+++ b/android_webview/glue/BUILD.gn
@@ -7,26 +7,8 @@
 import("generate_resource_rewriter.gni")
 import("glue.gni")
 
-# There are two copies of this file: one upstream and one downstream,
-# all targets defined in this file will finally generate two targets.
-# is_upstream could be used to differentiate those two targets, see
-# 'glue' target for details.
-is_upstream = rebase_path(".", "//android_webview/glue") == "."
-
-webview_framework_ijar = "frameworks.interface.jar"
 webview_public_framework_ijar = "frameworks.public.interface.jar"
 
-# Mark webview_framework_ijar is used, otherwise it isn't used if there
-# is no internal code.
-assert(webview_framework_ijar != "")
-
-if (defined(webview_internal_framework_jar)) {
-  generate_interface_jar("framework_ijar") {
-    input_jar = webview_internal_framework_jar
-    output_jar = "$target_out_dir/$webview_framework_ijar"
-  }
-}
-
 generate_interface_jar("public_framework_ijar") {
   input_jar = webview_public_framework_jar
   output_jar = "$target_out_dir/$webview_public_framework_ijar"
@@ -43,16 +25,8 @@
   deps = glue_library_deps
   srcjar_deps = [ ":glue_resource_rewriter" ]
 
-  # Always build upstream or downstream target with public or internal
-  # framework jar respectively.
-  if (is_upstream) {
-    alternative_android_sdk_ijar_dep = ":public_framework_ijar"
-    _ijar = webview_public_framework_ijar
-  } else {
-    assert(defined(webview_internal_framework_jar))
-    alternative_android_sdk_ijar_dep = ":framework_ijar"
-    _ijar = webview_framework_ijar
-  }
+  alternative_android_sdk_ijar_dep = ":public_framework_ijar"
+  _ijar = webview_public_framework_ijar
   _ijar_dir = get_label_info(alternative_android_sdk_ijar_dep, "target_out_dir")
   alternative_android_sdk_ijar = "$_ijar_dir/$_ijar"
   java_files = [
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
index 1da23803..e9a8012 100644
--- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
+++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java
@@ -739,4 +739,31 @@
         awContents = createAwTestContainerView(mContentsClient).getAwContents();
         awContents.resumeTimers();
     }
+
+    /** Regression test for https://crbug.com/732976. Load a data URL, then immediately
+     * after that load a javascript URL. The data URL navigation shouldn't be blocked.
+     */
+    @LargeTest
+    @Feature({"AndroidWebView"})
+    public void testJavaScriptUrlAfterLoadData() throws Throwable {
+        AwTestContainerView testView = createAwTestContainerViewOnMainSync(mContentsClient);
+        final AwContents awContents = testView.getAwContents();
+        getInstrumentation().runOnMainSync(new Runnable() {
+            @Override
+            public void run() {
+                // Run javascript navigation immediately, without waiting for the completion of data
+                // URL.
+                awContents.loadData("<html>test</html>", "text/html", "utf-8");
+                awContents.loadUrl("javascript: void(0)");
+            }
+        });
+
+        mContentsClient.getOnPageFinishedHelper().waitForCallback(
+                0, 1, WAIT_TIMEOUT_MS, TimeUnit.MILLISECONDS);
+        assertEquals("data:text/html,<html>test</html>", awContents.getLastCommittedUrl());
+
+        TestAwContentsClient.AddMessageToConsoleHelper consoleHelper =
+                mContentsClient.getAddMessageToConsoleHelper();
+        assertEquals(0, consoleHelper.getMessages().size());
+    }
 }
diff --git a/ash/root_window_controller_unittest.cc b/ash/root_window_controller_unittest.cc
index 706b57f..6695dbb 100644
--- a/ash/root_window_controller_unittest.cc
+++ b/ash/root_window_controller_unittest.cc
@@ -911,10 +911,10 @@
   ASSERT_TRUE(keyboard_container);
   keyboard_container->Show();
 
-  aura::Window* keyboard_window =
-      keyboard::KeyboardController::GetInstance()->ui()->GetKeyboardWindow();
-  keyboard_window->SetBounds(gfx::Rect());
-  keyboard_window->Show();
+  aura::Window* contents_window =
+      keyboard::KeyboardController::GetInstance()->ui()->GetContentsWindow();
+  contents_window->SetBounds(gfx::Rect());
+  contents_window->Show();
 
   // Make sure no pending mouse events in the queue.
   RunAllPendingInMessageLoop();
@@ -922,7 +922,7 @@
   ui::test::TestEventHandler handler;
   root_window->AddPreTargetHandler(&handler);
 
-  ui::test::EventGenerator event_generator(root_window, keyboard_window);
+  ui::test::EventGenerator event_generator(root_window, contents_window);
   event_generator.ClickLeftButton();
   int expected_mouse_presses = 1;
   EXPECT_EQ(expected_mouse_presses, handler.num_mouse_events() / 2);
@@ -965,10 +965,10 @@
   keyboard_container->Show();
   keyboard::KeyboardController* controller =
       keyboard::KeyboardController::GetInstance();
-  aura::Window* keyboard_window = controller->ui()->GetKeyboardWindow();
-  keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
+  aura::Window* contents_window = controller->ui()->GetContentsWindow();
+  contents_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
       root_window->bounds(), 100));
-  keyboard_window->Show();
+  contents_window->Show();
 
   gfx::Rect before =
       display::Screen::GetScreen()->GetPrimaryDisplay().work_area();
@@ -999,16 +999,16 @@
   ASSERT_TRUE(keyboard_container);
   keyboard_container->Show();
 
-  aura::Window* keyboard_window =
-      keyboard::KeyboardController::GetInstance()->ui()->GetKeyboardWindow();
-  keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
+  aura::Window* contents_window =
+      keyboard::KeyboardController::GetInstance()->ui()->GetContentsWindow();
+  contents_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
       root_window->bounds(), 100));
 
   ui::test::TestEventHandler handler;
   root_window->AddPreTargetHandler(&handler);
   ui::test::EventGenerator root_window_event_generator(root_window);
   ui::test::EventGenerator keyboard_event_generator(root_window,
-                                                    keyboard_window);
+                                                    contents_window);
 
   views::Widget* modal_widget = CreateModalWidget(gfx::Rect(300, 10, 100, 100));
 
@@ -1048,10 +1048,10 @@
   keyboard_container->Show();
 
   const int keyboard_height = 100;
-  aura::Window* keyboard_window = ui->GetKeyboardWindow();
-  keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
+  aura::Window* contents_window = ui->GetContentsWindow();
+  contents_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
       root_window->bounds(), keyboard_height));
-  keyboard_window->Show();
+  contents_window->Show();
 
   ui->EnsureCaretInWorkArea();
   ASSERT_EQ(root_window->bounds().width(),
@@ -1094,10 +1094,10 @@
       primary_root_window, kShellWindowId_VirtualKeyboardContainer);
   ASSERT_TRUE(keyboard_container);
   keyboard_container->Show();
-  aura::Window* keyboard_window = ui->GetKeyboardWindow();
-  keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
+  aura::Window* contents_window = ui->GetContentsWindow();
+  contents_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
       primary_root_window->bounds(), keyboard_height));
-  keyboard_window->Show();
+  contents_window->Show();
 
   ui->EnsureCaretInWorkArea();
   EXPECT_TRUE(primary_root_window->GetBoundsInScreen().Contains(
@@ -1110,7 +1110,7 @@
   // Move the keyboard into the secondary display and check that the keyboard
   // doesn't cover the window on the primary screen.
   keyboard_controller->ShowKeyboardInDisplay(secondary_display_id);
-  keyboard_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
+  contents_window->SetBounds(keyboard::FullWidthKeyboardBoundsFromRootBounds(
       secondary_root_window->bounds(), keyboard_height));
 
   ui->EnsureCaretInWorkArea();
@@ -1140,11 +1140,11 @@
   keyboard_container->Show();
 
   const int keyboard_height = 200;
-  aura::Window* keyboard_window = ui->GetKeyboardWindow();
+  aura::Window* contents_window = ui->GetContentsWindow();
   gfx::Rect keyboard_bounds = keyboard::FullWidthKeyboardBoundsFromRootBounds(
       root_window->bounds(), keyboard_height);
-  keyboard_window->SetBounds(keyboard_bounds);
-  keyboard_window->Show();
+  contents_window->SetBounds(keyboard_bounds);
+  contents_window->Show();
 
   ui::test::EventGenerator generator(root_window);
 
@@ -1217,7 +1217,7 @@
   keyboard::KeyboardController* keyboard_controller =
       keyboard::KeyboardController::GetInstance();
   keyboard_controller->ShowKeyboard(false);
-  keyboard_controller->ui()->GetKeyboardWindow()->SetBounds(
+  keyboard_controller->ui()->GetContentsWindow()->SetBounds(
       gfx::Rect(0, 400, 800, 200));
   EXPECT_EQ("0,400 800x200", keyboard_container->bounds().ToString());
 
diff --git a/ash/system/power/tablet_power_button_controller.cc b/ash/system/power/tablet_power_button_controller.cc
index 8ca8cfa..75e4d8c 100644
--- a/ash/system/power/tablet_power_button_controller.cc
+++ b/ash/system/power/tablet_power_button_controller.cc
@@ -176,6 +176,8 @@
         base::TimeDelta::FromMilliseconds(kIgnorePowerButtonAfterResumeMs)) {
       force_off_on_button_up_ = false;
     }
+
+    last_button_down_time_ = tick_clock_->NowTicks();
     screen_off_when_power_button_down_ = brightness_level_is_zero_;
     SetDisplayForcedOff(false);
     StartShutdownTimer();
@@ -184,13 +186,20 @@
     if (power_button_down_was_spurious_)
       return;
 
+    const base::TimeTicks previous_up_time = last_button_up_time_;
+    last_button_up_time_ = tick_clock_->NowTicks();
+
+    if (max_accelerometer_samples_) {
+      base::TimeDelta duration = last_button_up_time_ - last_button_down_time_;
+      VLOG(1) << "Power button released after " << duration.InMilliseconds()
+              << " ms";
+    }
+
     // When power button is released, cancel shutdown animation whenever it is
     // still cancellable.
     if (controller_->CanCancelShutdownAnimation())
       controller_->CancelShutdownAnimation();
 
-    const base::TimeTicks previous_up_time = last_button_up_time_;
-    last_button_up_time_ = tick_clock_->NowTicks();
     // Ignore the event if it comes too soon after the last one.
     if (timestamp - previous_up_time <=
         base::TimeDelta::FromMilliseconds(kIgnoreRepeatedButtonUpMs)) {
diff --git a/ash/system/power/tablet_power_button_controller.h b/ash/system/power/tablet_power_button_controller.h
index ab89f72..c660503 100644
--- a/ash/system/power/tablet_power_button_controller.h
+++ b/ash/system/power/tablet_power_button_controller.h
@@ -164,7 +164,8 @@
   // updated in SuspendDone().
   base::TimeTicks last_resume_time_;
 
-  // Saves the most recent timestamp that power button is released.
+  // Saves the most recent timestamp that power button is pressed and released.
+  base::TimeTicks last_button_down_time_;
   base::TimeTicks last_button_up_time_;
 
   // True if power button released should force off display.
diff --git a/ash/test/test_keyboard_ui.cc b/ash/test/test_keyboard_ui.cc
index f0d03c1..375a9b16 100644
--- a/ash/test/test_keyboard_ui.cc
+++ b/ash/test/test_keyboard_ui.cc
@@ -15,7 +15,7 @@
 TestKeyboardUI::TestKeyboardUI() {}
 TestKeyboardUI::~TestKeyboardUI() {}
 
-bool TestKeyboardUI::HasKeyboardWindow() const {
+bool TestKeyboardUI::HasContentsWindow() const {
   return !!keyboard_;
 }
 
@@ -23,7 +23,7 @@
   return true;
 }
 
-aura::Window* TestKeyboardUI::GetKeyboardWindow() {
+aura::Window* TestKeyboardUI::GetContentsWindow() {
   if (!keyboard_) {
     keyboard_.reset(new aura::Window(&delegate_));
     keyboard_->Init(ui::LAYER_NOT_DRAWN);
diff --git a/ash/test/test_keyboard_ui.h b/ash/test/test_keyboard_ui.h
index cd46236..aab17d0 100644
--- a/ash/test/test_keyboard_ui.h
+++ b/ash/test/test_keyboard_ui.h
@@ -23,9 +23,9 @@
   TestKeyboardUI();
   ~TestKeyboardUI() override;
 
-  bool HasKeyboardWindow() const override;
+  bool HasContentsWindow() const override;
   bool ShouldWindowOverscroll(aura::Window* window) const override;
-  aura::Window* GetKeyboardWindow() override;
+  aura::Window* GetContentsWindow() override;
 
  private:
   // Overridden from keyboard::KeyboardUI:
diff --git a/ash/wm/always_on_top_controller_unittest.cc b/ash/wm/always_on_top_controller_unittest.cc
index 058fc04..875ae023 100644
--- a/ash/wm/always_on_top_controller_unittest.cc
+++ b/ash/wm/always_on_top_controller_unittest.cc
@@ -77,13 +77,13 @@
       Shell::GetContainer(root_window, kShellWindowId_VirtualKeyboardContainer);
   ASSERT_TRUE(keyboard_container);
   keyboard_container->Show();
-  aura::Window* keyboard_window =
-      keyboard_controller->ui()->GetKeyboardWindow();
+  aura::Window* contents_window =
+      keyboard_controller->ui()->GetContentsWindow();
   const int kKeyboardHeight = 200;
   gfx::Rect keyboard_bounds = keyboard::FullWidthKeyboardBoundsFromRootBounds(
       root_window->bounds(), kKeyboardHeight);
-  keyboard_window->SetBounds(keyboard_bounds);
-  keyboard_window->Show();
+  contents_window->SetBounds(keyboard_bounds);
+  contents_window->Show();
   keyboard_controller->NotifyKeyboardBoundsChanging(keyboard_bounds);
   // Verify that test manager was notified of bounds change.
   ASSERT_TRUE(manager->keyboard_bounds_changed());
diff --git a/ash/wm/lock_action_handler_layout_manager_unittest.cc b/ash/wm/lock_action_handler_layout_manager_unittest.cc
index ce4836f..6ff9332 100644
--- a/ash/wm/lock_action_handler_layout_manager_unittest.cc
+++ b/ash/wm/lock_action_handler_layout_manager_unittest.cc
@@ -135,7 +135,7 @@
 
     if (show) {
       keyboard->ShowKeyboard(true);
-      keyboard->ui()->GetKeyboardWindow()->SetBounds(
+      keyboard->ui()->GetContentsWindow()->SetBounds(
           keyboard::FullWidthKeyboardBoundsFromRootBounds(
               Shell::GetPrimaryRootWindow()->bounds(), kVirtualKeyboardHeight));
     } else {
diff --git a/ash/wm/lock_layout_manager_unittest.cc b/ash/wm/lock_layout_manager_unittest.cc
index 67ab3b3..e6ad47f4 100644
--- a/ash/wm/lock_layout_manager_unittest.cc
+++ b/ash/wm/lock_layout_manager_unittest.cc
@@ -91,8 +91,8 @@
 
     if (show) {
       keyboard->ShowKeyboard(true);
-      if (keyboard->ui()->GetKeyboardWindow()->bounds().height() == 0) {
-        keyboard->ui()->GetKeyboardWindow()->SetBounds(
+      if (keyboard->ui()->GetContentsWindow()->bounds().height() == 0) {
+        keyboard->ui()->GetContentsWindow()->SetBounds(
             keyboard::FullWidthKeyboardBoundsFromRootBounds(
                 Shell::GetPrimaryRootWindow()->bounds(),
                 kVirtualKeyboardHeight));
@@ -234,7 +234,7 @@
   gfx::Rect target_bounds(screen_bounds);
   target_bounds.set_height(
       target_bounds.height() -
-      keyboard->ui()->GetKeyboardWindow()->bounds().height());
+      keyboard->ui()->GetContentsWindow()->bounds().height());
   EXPECT_EQ(target_bounds.ToString(), window->GetBoundsInScreen().ToString());
   ShowKeyboard(false);
 
diff --git a/ash/wm/system_modal_container_layout_manager_unittest.cc b/ash/wm/system_modal_container_layout_manager_unittest.cc
index ba2a592..1f07de9 100644
--- a/ash/wm/system_modal_container_layout_manager_unittest.cc
+++ b/ash/wm/system_modal_container_layout_manager_unittest.cc
@@ -193,8 +193,8 @@
 
     if (show) {
       keyboard->ShowKeyboard(true);
-      if (keyboard->ui()->GetKeyboardWindow()->bounds().height() == 0) {
-        keyboard->ui()->GetKeyboardWindow()->SetBounds(
+      if (keyboard->ui()->GetContentsWindow()->bounds().height() == 0) {
+        keyboard->ui()->GetContentsWindow()->SetBounds(
             keyboard::FullWidthKeyboardBoundsFromRootBounds(
                 Shell::GetPrimaryRootWindow()->bounds(), 100));
       }
diff --git a/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc b/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc
index 1a540bd..81c31f0d 100644
--- a/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc
+++ b/ash/wm/workspace/workspace_layout_manager_keyboard_unittest.cc
@@ -122,7 +122,7 @@
 
   // Open keyboard in non-sticky mode.
   kb_controller->ShowKeyboard(false);
-  kb_controller->ui()->GetKeyboardWindow()->SetBounds(
+  kb_controller->ui()->GetContentsWindow()->SetBounds(
       keyboard::FullWidthKeyboardBoundsFromRootBounds(
           Shell::GetPrimaryRootWindow()->bounds(), 100));
 
@@ -171,7 +171,7 @@
 
   // Open keyboard in non-sticky mode.
   kb_controller->ShowKeyboard(false);
-  kb_controller->ui()->GetKeyboardWindow()->SetBounds(
+  kb_controller->ui()->GetContentsWindow()->SetBounds(
       keyboard::FullWidthKeyboardBoundsFromRootBounds(
           Shell::GetPrimaryRootWindow()->bounds(), 100));
 
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java
index b2ae7a3c..0154363 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java
@@ -13,10 +13,14 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
+import android.os.SystemClock;
 
 import org.chromium.base.Log;
 import org.chromium.base.TraceEvent;
 import org.chromium.base.VisibleForTesting;
+import org.chromium.base.metrics.CachedMetrics;
+
+import java.util.concurrent.TimeUnit;
 
 import javax.annotation.Nullable;
 
@@ -145,6 +149,16 @@
         }
     }
 
+    // CachedMetrics used from this class, because this class can run before native library is
+    // loaded.
+    private static final CachedMetrics.TimesHistogramSample sOnServiceConnectedTimesMetric =
+            new CachedMetrics.TimesHistogramSample(
+                    "Android.ChildProcessLauncher.OnServiceConnectedTime", TimeUnit.MILLISECONDS);
+    private static final CachedMetrics
+            .BooleanHistogramSample sOnServiceConnectedTimesMetricTimedOut =
+            new CachedMetrics.BooleanHistogramSample(
+                    "Android.ChildProcessLauncher.OnServiceConnectedTimedOut");
+
     private final Handler mLauncherHandler;
     private final Context mContext;
     private final ComponentName mServiceName;
@@ -224,6 +238,9 @@
     // Set to true once unbind() was called.
     private boolean mUnbound;
 
+    // Timestamp when watchdog was last reset, which is equivalent to when start was called.
+    private long mLastWatchdogResetTimestamp;
+
     public ChildProcessConnection(Context context, ComponentName serviceName,
             boolean bindAsExternalService, Bundle serviceBundle,
             ChildProcessCreationParams creationParams) {
@@ -376,6 +393,10 @@
         }
         try {
             TraceEvent.begin("ChildProcessConnection.ChildServiceConnection.onServiceConnected");
+            sOnServiceConnectedTimesMetric.record(
+                    SystemClock.elapsedRealtime() - mLastWatchdogResetTimestamp);
+            sOnServiceConnectedTimesMetricTimedOut.record(false);
+
             mDidOnServiceConnected = true;
             mService = IChildProcessService.Stub.asInterface(service);
 
@@ -631,12 +652,13 @@
                 assert !mDidOnServiceConnected;
                 assert mServiceCallback == null;
                 mOnServiceConnectedWatchDog = null;
-                // TODO(boliu): Add a UMA here.
+                sOnServiceConnectedTimesMetricTimedOut.record(true);
                 if (!retryOnTimeout) return;
                 unbindAll();
                 start(useStrongBinding, serviceCallback, retryOnTimeout);
             }
         };
+        mLastWatchdogResetTimestamp = SystemClock.elapsedRealtime();
         mLauncherHandler.postDelayed(mOnServiceConnectedWatchDog, BIND_SERVICE_TIMEOUT_IN_MS);
     }
 
diff --git a/base/synchronization/waitable_event_watcher_unittest.cc b/base/synchronization/waitable_event_watcher_unittest.cc
index c44c1cb..7eacd7fc 100644
--- a/base/synchronization/waitable_event_watcher_unittest.cc
+++ b/base/synchronization/waitable_event_watcher_unittest.cc
@@ -226,6 +226,54 @@
   }
 }
 
+// Tests deleting the WaitableEventWatcher between signaling the event and
+// when the callback should be run.
+TEST_P(WaitableEventWatcherDeletionTest, DeleteWatcherBeforeCallback) {
+  MessageLoop::Type message_loop_type;
+  bool delay_after_delete;
+  std::tie(message_loop_type, delay_after_delete) = GetParam();
+
+  MessageLoop message_loop(message_loop_type);
+  scoped_refptr<SingleThreadTaskRunner> task_runner =
+      message_loop.task_runner();
+
+  // Flag used to esnure that the |watcher_callback| never runs.
+  bool did_callback = false;
+
+  WaitableEvent event(WaitableEvent::ResetPolicy::AUTOMATIC,
+                      WaitableEvent::InitialState::NOT_SIGNALED);
+  auto watcher = MakeUnique<WaitableEventWatcher>();
+
+  // Queue up a series of tasks:
+  // 1. StartWatching the WaitableEvent
+  // 2. Signal the event (which will result in another task getting posted to
+  //    the |task_runner|)
+  // 3. Delete the WaitableEventWatcher
+  // 4. WaitableEventWatcher callback should run (from #2)
+
+  WaitableEventWatcher::EventCallback watcher_callback = BindOnce(
+      [](bool* did_callback, WaitableEvent*) {
+        *did_callback = true;
+      },
+      Unretained(&did_callback));
+
+  task_runner->PostTask(
+      FROM_HERE, BindOnce(IgnoreResult(&WaitableEventWatcher::StartWatching),
+                          Unretained(watcher.get()), Unretained(&event),
+                          std::move(watcher_callback)));
+  task_runner->PostTask(FROM_HERE,
+                        BindOnce(&WaitableEvent::Signal, Unretained(&event)));
+  task_runner->DeleteSoon(FROM_HERE, std::move(watcher));
+  if (delay_after_delete) {
+    task_runner->PostTask(FROM_HERE, BindOnce(&PlatformThread::Sleep,
+                                              TimeDelta::FromMilliseconds(30)));
+  }
+
+  RunLoop().RunUntilIdle();
+
+  EXPECT_FALSE(did_callback);
+}
+
 INSTANTIATE_TEST_CASE_P(,
                         WaitableEventWatcherTest,
                         testing::ValuesIn(testing_message_loops));
diff --git a/build/android/lint/suppressions.xml b/build/android/lint/suppressions.xml
index b483735..ead20a9 100644
--- a/build/android/lint/suppressions.xml
+++ b/build/android/lint/suppressions.xml
@@ -350,7 +350,6 @@
     <ignore regexp="remoting/android/java/res/drawable-hdpi/ic_zoom_in.png"/>
     <ignore regexp="remoting/android/java/res/drawable-hdpi/ic_zoom_out.png"/>
     <ignore regexp="remoting/android/java/res/layout/navigation_list_item.xml"/>
-    <ignore regexp="remoting/android/java/res/mipmap-hdpi/logo_remote_desktop_launcher.png"/>
     <ignore regexp="remoting/android/java/res/values-v17/styles.xml"/>
     <!-- Used by Android's policies system -->
     <ignore regexp="restriction_values.xml"/>
@@ -465,4 +464,8 @@
     <ignore regexp="chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDialog.java"/>
     <ignore regexp="chrome/android/java/src/org/chromium/chrome/browser/signin/SigninAndSyncView.java"/>
   </issue>
+  <issue id="IconLauncherFormat" severity="ignore">
+    <!-- TODO(crbug.com/739746): Remove after lint version has been updated. -->
+    <ignore regexp="remoting/android/java/res/mipmap-anydpi-v26/ic_launcher.xml"/>
+  </issue>
 </lint>
diff --git a/build/android/pylib/local/device/local_device_instrumentation_test_run.py b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
index 0365680..b51330d2 100644
--- a/build/android/pylib/local/device/local_device_instrumentation_test_run.py
+++ b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
@@ -424,11 +424,6 @@
 
     logcat_url = logmon.GetLogcatURL()
     duration_ms = time_ms() - start_ms
-    if flags_to_add or flags_to_remove:
-      self._flag_changers[str(device)].Restore()
-    if test_timeout_scale:
-      valgrind_tools.SetChromeTimeoutScale(
-          device, self._test_instance.timeout_scale)
 
     # TODO(jbudorick): Make instrumentation tests output a JSON so this
     # doesn't have to parse the output.
@@ -436,21 +431,54 @@
         self._test_instance.ParseAmInstrumentRawOutput(output))
     results = self._test_instance.GenerateTestResults(
         result_code, result_bundle, statuses, start_ms, duration_ms)
+
+    def restore_flags():
+      if flags_to_add or flags_to_remove:
+        self._flag_changers[str(device)].Restore()
+
+    def restore_timeout_scale():
+      if test_timeout_scale:
+        valgrind_tools.SetChromeTimeoutScale(
+            device, self._test_instance.timeout_scale)
+
+    def handle_coverage_data():
+      if self._test_instance.coverage_directory:
+        device.PullFile(coverage_directory,
+            self._test_instance.coverage_directory)
+        device.RunShellCommand(
+            'rm -f %s' % posixpath.join(coverage_directory, '*'),
+            check_return=True, shell=True)
+
+    def handle_render_test_data():
+      if _IsRenderTest(test):
+        # Render tests do not cause test failure by default. So we have to check
+        # to see if any failure images were generated even if the test does not
+        # fail.
+        try:
+          self._ProcessRenderTestResults(
+              device, render_tests_device_output_dir, results)
+        finally:
+          device.RemovePath(render_tests_device_output_dir,
+                            recursive=True, force=True)
+
+    # While constructing the TestResult objects, we can parallelize several
+    # steps that involve ADB. These steps should NOT depend on any info in
+    # the results! Things such as whether the test CRASHED have not yet been
+    # determined.
+    post_test_steps = [restore_flags, restore_timeout_scale,
+                       handle_coverage_data, handle_render_test_data]
+    if self._env.concurrent_adb:
+      post_test_step_thread_group = reraiser_thread.ReraiserThreadGroup(
+          reraiser_thread.ReraiserThread(f) for f in post_test_steps)
+      post_test_step_thread_group.StartAll(will_block=True)
+    else:
+      for step in post_test_steps:
+        step()
+
     for result in results:
       if logcat_url:
         result.SetLink('logcat', logcat_url)
 
-    if _IsRenderTest(test):
-      # Render tests do not cause test failure by default. So we have to check
-      # to see if any failure images were generated even if the test does not
-      # fail.
-      try:
-        self._ProcessRenderTestResults(
-            device, render_tests_device_output_dir, results)
-      finally:
-        device.RemovePath(render_tests_device_output_dir,
-                          recursive=True, force=True)
-
     # Update the result name if the test used flags.
     if flags_to_add or flags_to_remove:
       for r in results:
@@ -503,12 +531,6 @@
       logging.debug('raw output from %s:', test_display_name)
       for l in output:
         logging.debug('  %s', l)
-    if self._test_instance.coverage_directory:
-      device.PullFile(coverage_directory,
-          self._test_instance.coverage_directory)
-      device.RunShellCommand(
-          'rm -f %s' % posixpath.join(coverage_directory, '*'),
-          check_return=True, shell=True)
     if self._test_instance.store_tombstones:
       tombstones_url = None
       for result in results:
@@ -525,6 +547,9 @@
             tombstones_url = logdog_helper.text(
                 stream_name, '\n'.join(resolved_tombstones))
           result.SetLink('tombstones', tombstones_url)
+
+    if self._env.concurrent_adb:
+      post_test_step_thread_group.JoinAll()
     return results, None
 
   def _SaveScreenshot(self, device, screenshot_host_dir, screenshot_device_file,
diff --git a/build/config/compiler/compiler.gni b/build/config/compiler/compiler.gni
index 73f3bf0..e1b72be0 100644
--- a/build/config/compiler/compiler.gni
+++ b/build/config/compiler/compiler.gni
@@ -78,11 +78,11 @@
     enable_frame_pointers = true
   }
 } else if (is_chromeos) {
-  # ChromeOS requires frame pointers in x64 builds, to support CWP.
-  # TODO(711784): Building ARM Thumb without frame pointers can lead to code
-  # in ChromeOS which triggers some ARM A12/A17 errata. They can be disabled
-  # on non-x64 once that is resolved.
-  enable_frame_pointers = true
+  # ChromeOS generally prefers frame pointers, to support CWP.
+  # However, Clang does not currently generate usable frame pointers in ARM
+  # 32-bit builds (https://bugs.llvm.org/show_bug.cgi?id=18505) so disable them
+  # there to avoid the unnecessary overhead.
+  enable_frame_pointers = current_cpu != "arm"
 } else if (current_cpu == "arm64") {
   # Ensure that stacks from arm64 crash dumps are usable (crbug.com/391706).
   enable_frame_pointers = true
@@ -100,6 +100,7 @@
 can_unwind_with_frame_pointers = enable_frame_pointers
 if (current_cpu == "arm" && arm_use_thumb) {
   # We cannot currently unwind ARM Thumb frame pointers correctly.
+  # See https://bugs.llvm.org/show_bug.cgi?id=18505
   can_unwind_with_frame_pointers = false
 } else if (is_win) {
   # Windows 32-bit does provide frame pointers, but the compiler does not
diff --git a/build/secondary/third_party/libjpeg_turbo/BUILD.gn b/build/secondary/third_party/libjpeg_turbo/BUILD.gn
index 941c825d..265d30b 100644
--- a/build/secondary/third_party/libjpeg_turbo/BUILD.gn
+++ b/build/secondary/third_party/libjpeg_turbo/BUILD.gn
@@ -86,7 +86,6 @@
 
     if (is_win) {
       defines += [ "MSVC" ]
-      include_dirs = [ "win" ]
       if (current_cpu == "x86") {
         defines += [ "WIN32" ]
       } else {
@@ -94,10 +93,8 @@
       }
     } else if (is_mac || is_ios) {
       defines += [ "MACHO" ]
-      include_dirs = [ "mac" ]
-    } else if (is_linux || is_android) {
+    } else if (is_linux || is_android || is_fuchsia) {
       defines += [ "ELF" ]
-      include_dirs = [ "linux" ]
     }
   }
 }
diff --git a/cc/BUILD.gn b/cc/BUILD.gn
index d491724..359e2e2 100644
--- a/cc/BUILD.gn
+++ b/cc/BUILD.gn
@@ -594,8 +594,6 @@
     "test/ordered_simple_task_runner.h",
     "test/ordered_texture_map.cc",
     "test/ordered_texture_map.h",
-    "test/paths.cc",
-    "test/paths.h",
     "test/pixel_comparator.cc",
     "test/pixel_comparator.h",
     "test/pixel_test.cc",
@@ -620,8 +618,6 @@
     "test/stub_layer_tree_host_client.h",
     "test/stub_layer_tree_host_single_thread_client.cc",
     "test/stub_layer_tree_host_single_thread_client.h",
-    "test/surface_aggregator_test_helpers.cc",
-    "test/surface_aggregator_test_helpers.h",
     "test/surface_hittest_test_helpers.cc",
     "test/surface_hittest_test_helpers.h",
     "test/task_graph_runner_test_template.cc",
@@ -640,8 +636,6 @@
     "test/test_image_factory.h",
     "test/test_in_process_context_provider.cc",
     "test/test_in_process_context_provider.h",
-    "test/test_layer_tree_frame_sink.cc",
-    "test/test_layer_tree_frame_sink.h",
     "test/test_layer_tree_host_base.cc",
     "test/test_layer_tree_host_base.h",
     "test/test_occlusion_tracker.h",
@@ -674,6 +668,8 @@
     "//cc/surfaces",
     "//cc/surfaces:surface_id",
     "//components/viz/common",
+    "//components/viz/service",
+    "//components/viz/test:test_support",
     "//gpu/command_buffer/client:gles2_c_lib",
     "//gpu/command_buffer/client:gles2_implementation",
     "//gpu/command_buffer/common:gles2_utils",
@@ -845,19 +841,13 @@
     "animation/transform_operations_unittest.cc",
 
     # Surfaces test files.
-    "surfaces/compositor_frame_sink_support_unittest.cc",
-    "surfaces/direct_layer_tree_frame_sink_unittest.cc",
-    "surfaces/display_scheduler_unittest.cc",
-    "surfaces/display_unittest.cc",
     "surfaces/frame_sink_manager_unittest.cc",
     "surfaces/referenced_surface_tracker_unittest.cc",
-    "surfaces/surface_aggregator_unittest.cc",
     "surfaces/surface_hittest_unittest.cc",
     "surfaces/surface_manager_ref_unittest.cc",
     "surfaces/surface_sequence_generator_unittest.cc",
     "surfaces/surface_synchronization_unittest.cc",
     "surfaces/surface_unittest.cc",
-    "surfaces/surfaces_pixeltest.cc",
 
     # Setup.
     "test/cc_test_suite.cc",
@@ -867,7 +857,7 @@
 
   if (!is_android) {
     data = [
-      "test/data/",
+      "//components/viz/test/data/",
     ]
   }
 
@@ -885,6 +875,8 @@
     "//cc/surfaces:surface_id",
     "//cc/surfaces:surfaces",
     "//components/viz/common",
+    "//components/viz/service",
+    "//components/viz/test:test_support",
     "//gpu",
     "//gpu:test_support",
     "//gpu/command_buffer/client:gles2_interface",
@@ -919,7 +911,6 @@
     "raster/raster_buffer_provider_perftest.cc",
     "raster/task_graph_runner_perftest.cc",
     "raster/texture_compressor_perftest.cc",
-    "surfaces/surface_aggregator_perftest.cc",
     "test/cc_test_suite.cc",
     "test/cc_test_suite.h",
     "test/run_all_perftests.cc",
@@ -939,6 +930,7 @@
     "//cc/paint",
     "//cc/surfaces",
     "//cc/surfaces:surface_id",
+    "//components/viz/test:test_support",
     "//gpu",
     "//gpu:test_support",
     "//gpu/command_buffer/common:gles2_utils",
diff --git a/cc/DEPS b/cc/DEPS
index 6b2dad82..5ae24df7 100644
--- a/cc/DEPS
+++ b/cc/DEPS
@@ -36,4 +36,7 @@
     "+gpu/command_buffer/common",
     "+gpu/ipc",
   ],
+  ".*_(unit|pixel|perf)test.*\.cc": [
+    "+components/viz/test",
+  ],
 }
diff --git a/cc/ipc/frame_sink_manager.mojom b/cc/ipc/frame_sink_manager.mojom
index d77f0b5..ac51894 100644
--- a/cc/ipc/frame_sink_manager.mojom
+++ b/cc/ipc/frame_sink_manager.mojom
@@ -15,7 +15,7 @@
 import "ui/gfx/mojo/color_space.mojom";
 
 // See ui/compositor/compositor.h: ContextFactoryPrivate.
-// The DisplayPrivate is used by privileged clients to talk to cc::Display.
+// The DisplayPrivate is used by privileged clients to talk to Display.
 // DisplayPrivate would eventually replace or be used by ContextFactoryPrivate.
 interface DisplayPrivate {
   SetDisplayVisible(bool visible);
@@ -32,7 +32,7 @@
 // through the frame sink manager host. Clients request a CompositorFrameSink
 // interface, and implement a CompositorFrameSinkClient interface. The frame
 // sink manager host holds one or more display CompositorFrameSinks that are
-// tied to a valid |surface_handle| and cc::Display. All other
+// tied to a valid |surface_handle| and Display. All other
 // CompositorFrameSinks must be parented by another CompositorFrameSink.
 // FrameSinkIds are fixed for a given client and are determined ahead of time.
 // Thus, a client will typically simply request a CompositorFrameSink from the
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc
index 216ba35..623ac76 100644
--- a/cc/layers/texture_layer_unittest.cc
+++ b/cc/layers/texture_layer_unittest.cc
@@ -34,13 +34,13 @@
 #include "cc/test/layer_test_common.h"
 #include "cc/test/layer_tree_test.h"
 #include "cc/test/stub_layer_tree_host_single_thread_client.h"
-#include "cc/test/test_layer_tree_frame_sink.h"
 #include "cc/test/test_task_graph_runner.h"
 #include "cc/test/test_web_graphics_context_3d.h"
 #include "cc/trees/blocking_task_runner.h"
 #include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "cc/trees/single_thread_proxy.h"
+#include "components/viz/test/test_layer_tree_frame_sink.h"
 #include "gpu/GLES2/gl2extchromium.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -636,7 +636,7 @@
  public:
   TextureLayerImplWithMailboxThreadedCallback() = default;
 
-  std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+  std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
       const RendererSettings& renderer_settings,
       double refresh_rate,
       scoped_refptr<ContextProvider> compositor_context_provider,
@@ -645,7 +645,7 @@
     bool synchronous_composite =
         !HasImplThread() &&
         !layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
-    return base::MakeUnique<TestLayerTreeFrameSink>(
+    return base::MakeUnique<viz::TestLayerTreeFrameSink>(
         compositor_context_provider, std::move(worker_context_provider),
         shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings,
         ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync,
diff --git a/cc/output/bsp_tree_perftest.cc b/cc/output/bsp_tree_perftest.cc
index f8f16d0..d297eb0 100644
--- a/cc/output/bsp_tree_perftest.cc
+++ b/cc/output/bsp_tree_perftest.cc
@@ -23,9 +23,9 @@
 #include "cc/test/fake_layer_tree_host_client.h"
 #include "cc/test/layer_tree_json_parser.h"
 #include "cc/test/layer_tree_test.h"
-#include "cc/test/paths.h"
 #include "cc/trees/layer_tree_host_common.h"
 #include "cc/trees/layer_tree_impl.h"
+#include "components/viz/test/paths.h"
 #include "testing/perf/perf_test.h"
 
 namespace cc {
@@ -60,7 +60,7 @@
 
   void ReadTestFile(const std::string& name) {
     base::FilePath test_data_dir;
-    ASSERT_TRUE(PathService::Get(CCPaths::DIR_TEST_DATA, &test_data_dir));
+    ASSERT_TRUE(PathService::Get(viz::Paths::DIR_TEST_DATA, &test_data_dir));
     base::FilePath json_file = test_data_dir.AppendASCII(name + ".json");
     ASSERT_TRUE(base::ReadFileToString(json_file, &json_));
   }
diff --git a/cc/surfaces/BUILD.gn b/cc/surfaces/BUILD.gn
index b91156bb..3636bbe 100644
--- a/cc/surfaces/BUILD.gn
+++ b/cc/surfaces/BUILD.gn
@@ -27,18 +27,8 @@
 cc_component("surfaces") {
   output_name = "cc_surfaces"
   sources = [
-    "compositor_frame_sink_support.cc",
-    "compositor_frame_sink_support.h",
-    "compositor_frame_sink_support_client.h",
-    "direct_layer_tree_frame_sink.cc",
-    "direct_layer_tree_frame_sink.h",
     "direct_surface_reference_factory.cc",
     "direct_surface_reference_factory.h",
-    "display.cc",
-    "display.h",
-    "display_client.h",
-    "display_scheduler.cc",
-    "display_scheduler.h",
     "frame_sink_manager.cc",
     "frame_sink_manager.h",
     "frame_sink_manager_client.h",
@@ -52,8 +42,6 @@
     "stub_surface_reference_factory.h",
     "surface.cc",
     "surface.h",
-    "surface_aggregator.cc",
-    "surface_aggregator.h",
     "surface_client.h",
     "surface_deadline_observer.h",
     "surface_dependency_deadline.cc",
diff --git a/cc/surfaces/DEPS b/cc/surfaces/DEPS
index 07703df..d0a78f5 100644
--- a/cc/surfaces/DEPS
+++ b/cc/surfaces/DEPS
@@ -1,4 +1,11 @@
 include_rules = [
   "+components/viz/common",
+  "+components/viz/service/display",
   "+mojo/public/cpp/bindings/struct_traits.h",
 ]
+
+specific_include_rules = {
+  ".*_unittest\.cc": [
+    "+components/viz/service/frame_sinks",
+  ],
+}
diff --git a/cc/surfaces/compositor_frame_sink_support.cc b/cc/surfaces/compositor_frame_sink_support.cc
deleted file mode 100644
index 666d0a12..0000000
--- a/cc/surfaces/compositor_frame_sink_support.cc
+++ /dev/null
@@ -1,373 +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/surfaces/compositor_frame_sink_support.h"
-
-#include <algorithm>
-#include <utility>
-
-#include "cc/output/compositor_frame.h"
-#include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
-#include "cc/surfaces/display.h"
-#include "cc/surfaces/frame_sink_manager.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_info.h"
-#include "cc/surfaces/surface_reference.h"
-
-namespace cc {
-
-// static
-std::unique_ptr<CompositorFrameSinkSupport> CompositorFrameSinkSupport::Create(
-    CompositorFrameSinkSupportClient* client,
-    FrameSinkManager* frame_sink_manager,
-    const viz::FrameSinkId& frame_sink_id,
-    bool is_root,
-    bool handles_frame_sink_id_invalidation,
-    bool needs_sync_tokens) {
-  std::unique_ptr<CompositorFrameSinkSupport> support =
-      base::WrapUnique(new CompositorFrameSinkSupport(
-          client, frame_sink_id, is_root, handles_frame_sink_id_invalidation,
-          needs_sync_tokens));
-  support->Init(frame_sink_manager);
-  return support;
-}
-
-CompositorFrameSinkSupport::~CompositorFrameSinkSupport() {
-  // Unregister |this| as a BeginFrameObserver so that the BeginFrameSource does
-  // not call into |this| after it's deleted.
-  SetNeedsBeginFrame(false);
-
-  // For display root surfaces the surface is no longer going to be visible.
-  // Make it unreachable from the top-level root.
-  if (referenced_local_surface_id_.has_value()) {
-    auto reference = MakeTopLevelRootReference(
-        viz::SurfaceId(frame_sink_id_, referenced_local_surface_id_.value()));
-    surface_manager_->RemoveSurfaceReferences({reference});
-  }
-
-  EvictCurrentSurface();
-  frame_sink_manager_->UnregisterFrameSinkManagerClient(frame_sink_id_);
-  if (handles_frame_sink_id_invalidation_)
-    frame_sink_manager_->InvalidateFrameSinkId(frame_sink_id_);
-}
-
-void CompositorFrameSinkSupport::OnSurfaceActivated(Surface* surface) {
-  DCHECK(surface->HasActiveFrame());
-  const CompositorFrame& frame = surface->GetActiveFrame();
-  if (!seen_first_frame_activation_) {
-    // SurfaceCreated only applies for the first Surface activation.
-    seen_first_frame_activation_ = true;
-
-    gfx::Size frame_size = frame.render_pass_list.back()->output_rect.size();
-    surface_manager_->SurfaceCreated(SurfaceInfo(
-        surface->surface_id(), frame.metadata.device_scale_factor, frame_size));
-  }
-  // Fire SurfaceCreated first so that a temporary reference is added before it
-  // is potentially transformed into a real reference by the client.
-  DCHECK(surface->active_referenced_surfaces());
-  UpdateSurfaceReferences(surface->surface_id().local_surface_id(),
-                          *surface->active_referenced_surfaces());
-  if (!surface_manager_->SurfaceModified(surface->surface_id(),
-                                         frame.metadata.begin_frame_ack)) {
-    TRACE_EVENT_INSTANT0("cc", "Damage not visible.", TRACE_EVENT_SCOPE_THREAD);
-    surface->RunDrawCallback();
-  }
-  surface_manager_->SurfaceActivated(surface);
-}
-
-void CompositorFrameSinkSupport::RefResources(
-    const std::vector<TransferableResource>& resources) {
-  surface_resource_holder_.RefResources(resources);
-}
-
-void CompositorFrameSinkSupport::UnrefResources(
-    const std::vector<ReturnedResource>& resources) {
-  surface_resource_holder_.UnrefResources(resources);
-}
-
-void CompositorFrameSinkSupport::ReturnResources(
-    const std::vector<ReturnedResource>& resources) {
-  if (resources.empty())
-    return;
-  if (!ack_pending_count_ && client_) {
-    client_->ReclaimResources(resources);
-    return;
-  }
-
-  std::copy(resources.begin(), resources.end(),
-            std::back_inserter(surface_returned_resources_));
-}
-
-void CompositorFrameSinkSupport::ReceiveFromChild(
-    const std::vector<TransferableResource>& resources) {
-  surface_resource_holder_.ReceiveFromChild(resources);
-}
-
-void CompositorFrameSinkSupport::SetBeginFrameSource(
-    BeginFrameSource* begin_frame_source) {
-  if (begin_frame_source_ && added_frame_observer_) {
-    begin_frame_source_->RemoveObserver(this);
-    added_frame_observer_ = false;
-  }
-  begin_frame_source_ = begin_frame_source;
-  UpdateNeedsBeginFramesInternal();
-}
-
-void CompositorFrameSinkSupport::EvictCurrentSurface() {
-  if (!current_surface_id_.is_valid())
-    return;
-  viz::SurfaceId to_destroy_surface_id = current_surface_id_;
-  current_surface_id_ = viz::SurfaceId();
-  surface_manager_->DestroySurface(to_destroy_surface_id);
-}
-
-void CompositorFrameSinkSupport::SetNeedsBeginFrame(bool needs_begin_frame) {
-  needs_begin_frame_ = needs_begin_frame;
-  UpdateNeedsBeginFramesInternal();
-}
-
-void CompositorFrameSinkSupport::DidNotProduceFrame(const BeginFrameAck& ack) {
-  TRACE_EVENT2("cc", "CompositorFrameSinkSupport::DidNotProduceFrame",
-               "ack.source_id", ack.source_id, "ack.sequence_number",
-               ack.sequence_number);
-  DCHECK_GE(ack.sequence_number, BeginFrameArgs::kStartingFrameNumber);
-
-  // |has_damage| is not transmitted, but false by default.
-  DCHECK(!ack.has_damage);
-
-  if (current_surface_id_.is_valid())
-    surface_manager_->SurfaceModified(current_surface_id_, ack);
-
-  if (begin_frame_source_)
-    begin_frame_source_->DidFinishFrame(this);
-}
-
-bool CompositorFrameSinkSupport::SubmitCompositorFrame(
-    const viz::LocalSurfaceId& local_surface_id,
-    CompositorFrame frame) {
-  TRACE_EVENT0("cc", "CompositorFrameSinkSupport::SubmitCompositorFrame");
-  DCHECK(local_surface_id.is_valid());
-  DCHECK(!frame.render_pass_list.empty());
-
-  ++ack_pending_count_;
-
-  // |has_damage| is not transmitted.
-  frame.metadata.begin_frame_ack.has_damage = true;
-  BeginFrameAck ack = frame.metadata.begin_frame_ack;
-  DCHECK_LE(BeginFrameArgs::kStartingFrameNumber, ack.sequence_number);
-
-  if (!ui::LatencyInfo::Verify(frame.metadata.latency_info,
-                               "RenderWidgetHostImpl::OnSwapCompositorFrame")) {
-    std::vector<ui::LatencyInfo>().swap(frame.metadata.latency_info);
-  }
-  for (ui::LatencyInfo& latency : frame.metadata.latency_info) {
-    if (latency.latency_components().size() > 0) {
-      latency.AddLatencyNumber(ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT,
-                               0, 0);
-    }
-  }
-
-  Surface* prev_surface =
-      surface_manager_->GetSurfaceForId(current_surface_id_);
-  Surface* current_surface = nullptr;
-  if (prev_surface &&
-      local_surface_id == current_surface_id_.local_surface_id()) {
-    current_surface = prev_surface;
-  } else {
-    viz::SurfaceId surface_id(frame_sink_id_, local_surface_id);
-    gfx::Size frame_size = frame.render_pass_list.back()->output_rect.size();
-    float device_scale_factor = frame.metadata.device_scale_factor;
-    SurfaceInfo surface_info(surface_id, device_scale_factor, frame_size);
-
-    if (!surface_info.is_valid()) {
-      TRACE_EVENT_INSTANT0("cc", "Invalid SurfaceInfo",
-                           TRACE_EVENT_SCOPE_THREAD);
-      EvictCurrentSurface();
-      std::vector<ReturnedResource> resources =
-          TransferableResource::ReturnResources(frame.resource_list);
-      ReturnResources(resources);
-      DidReceiveCompositorFrameAck();
-      return true;
-    }
-
-    current_surface = CreateSurface(surface_info);
-    current_surface_id_ = viz::SurfaceId(frame_sink_id_, local_surface_id);
-    surface_manager_->SurfaceDamageExpected(current_surface->surface_id(),
-                                            last_begin_frame_args_);
-  }
-
-  bool result = current_surface->QueueFrame(
-      std::move(frame),
-      base::Bind(&CompositorFrameSinkSupport::DidReceiveCompositorFrameAck,
-                 weak_factory_.GetWeakPtr()),
-      base::BindRepeating(&CompositorFrameSinkSupport::WillDrawSurface,
-                          weak_factory_.GetWeakPtr()));
-
-  if (!result) {
-    EvictCurrentSurface();
-    return false;
-  }
-
-  if (prev_surface && prev_surface != current_surface) {
-    current_surface->SetPreviousFrameSurface(prev_surface);
-    surface_manager_->DestroySurface(prev_surface->surface_id());
-  }
-
-  if (begin_frame_source_)
-    begin_frame_source_->DidFinishFrame(this);
-
-  return true;
-}
-
-void CompositorFrameSinkSupport::UpdateSurfaceReferences(
-    const viz::LocalSurfaceId& local_surface_id,
-    const std::vector<viz::SurfaceId>& active_referenced_surfaces) {
-  viz::SurfaceId surface_id(frame_sink_id_, local_surface_id);
-
-  const base::flat_set<viz::SurfaceId>& existing_referenced_surfaces =
-      surface_manager_->GetSurfacesReferencedByParent(surface_id);
-
-  base::flat_set<viz::SurfaceId> new_referenced_surfaces(
-      active_referenced_surfaces.begin(), active_referenced_surfaces.end(),
-      base::KEEP_FIRST_OF_DUPES);
-
-  // Populate list of surface references to add and remove by getting the
-  // difference between existing surface references and surface references for
-  // latest activated CompositorFrame.
-  std::vector<SurfaceReference> references_to_add;
-  std::vector<SurfaceReference> references_to_remove;
-  GetSurfaceReferenceDifference(surface_id, existing_referenced_surfaces,
-                                new_referenced_surfaces, &references_to_add,
-                                &references_to_remove);
-
-  // Check if this is a display root surface and the viz::SurfaceId is changing.
-  if (is_root_ && (!referenced_local_surface_id_.has_value() ||
-                   referenced_local_surface_id_.value() != local_surface_id)) {
-    // Make the new viz::SurfaceId reachable from the top-level root.
-    references_to_add.push_back(MakeTopLevelRootReference(surface_id));
-
-    // Make the old viz::SurfaceId unreachable from the top-level root if
-    // applicable.
-    if (referenced_local_surface_id_.has_value()) {
-      references_to_remove.push_back(MakeTopLevelRootReference(viz::SurfaceId(
-          frame_sink_id_, referenced_local_surface_id_.value())));
-    }
-
-    referenced_local_surface_id_ = local_surface_id;
-  }
-
-  // Modify surface references stored in SurfaceManager.
-  if (!references_to_add.empty())
-    surface_manager_->AddSurfaceReferences(references_to_add);
-  if (!references_to_remove.empty())
-    surface_manager_->RemoveSurfaceReferences(references_to_remove);
-}
-
-SurfaceReference CompositorFrameSinkSupport::MakeTopLevelRootReference(
-    const viz::SurfaceId& surface_id) {
-  return SurfaceReference(surface_manager_->GetRootSurfaceId(), surface_id);
-}
-
-void CompositorFrameSinkSupport::DidReceiveCompositorFrameAck() {
-  DCHECK_GT(ack_pending_count_, 0);
-  ack_pending_count_--;
-  if (!client_)
-    return;
-
-  client_->DidReceiveCompositorFrameAck(surface_returned_resources_);
-  surface_returned_resources_.clear();
-}
-
-void CompositorFrameSinkSupport::WillDrawSurface(
-    const viz::LocalSurfaceId& local_surface_id,
-    const gfx::Rect& damage_rect) {
-  if (client_)
-    client_->WillDrawSurface(local_surface_id, damage_rect);
-}
-
-void CompositorFrameSinkSupport::ClaimTemporaryReference(
-    const viz::SurfaceId& surface_id) {
-  surface_manager_->AssignTemporaryReference(surface_id, frame_sink_id_);
-}
-
-CompositorFrameSinkSupport::CompositorFrameSinkSupport(
-    CompositorFrameSinkSupportClient* client,
-    const viz::FrameSinkId& frame_sink_id,
-    bool is_root,
-    bool handles_frame_sink_id_invalidation,
-    bool needs_sync_tokens)
-    : client_(client),
-      frame_sink_id_(frame_sink_id),
-      surface_resource_holder_(this),
-      is_root_(is_root),
-      needs_sync_tokens_(needs_sync_tokens),
-      handles_frame_sink_id_invalidation_(handles_frame_sink_id_invalidation),
-      weak_factory_(this) {}
-
-void CompositorFrameSinkSupport::Init(FrameSinkManager* frame_sink_manager) {
-  frame_sink_manager_ = frame_sink_manager;
-  surface_manager_ = frame_sink_manager->surface_manager();
-  if (handles_frame_sink_id_invalidation_)
-    frame_sink_manager_->RegisterFrameSinkId(frame_sink_id_);
-  frame_sink_manager_->RegisterFrameSinkManagerClient(frame_sink_id_, this);
-}
-
-void CompositorFrameSinkSupport::OnBeginFrame(const BeginFrameArgs& args) {
-  UpdateNeedsBeginFramesInternal();
-  if (current_surface_id_.is_valid()) {
-    surface_manager_->SurfaceDamageExpected(current_surface_id_, args);
-  }
-  last_begin_frame_args_ = args;
-  if (client_)
-    client_->OnBeginFrame(args);
-}
-
-const BeginFrameArgs& CompositorFrameSinkSupport::LastUsedBeginFrameArgs()
-    const {
-  return last_begin_frame_args_;
-}
-
-void CompositorFrameSinkSupport::OnBeginFrameSourcePausedChanged(bool paused) {}
-
-void CompositorFrameSinkSupport::UpdateNeedsBeginFramesInternal() {
-  if (!begin_frame_source_)
-    return;
-
-  if (needs_begin_frame_ == added_frame_observer_)
-    return;
-
-  added_frame_observer_ = needs_begin_frame_;
-  if (needs_begin_frame_)
-    begin_frame_source_->AddObserver(this);
-  else
-    begin_frame_source_->RemoveObserver(this);
-}
-
-Surface* CompositorFrameSinkSupport::CreateSurface(
-    const SurfaceInfo& surface_info) {
-  seen_first_frame_activation_ = false;
-  return surface_manager_->CreateSurface(
-      weak_factory_.GetWeakPtr(), surface_info,
-      frame_sink_manager_->GetPrimaryBeginFrameSource(), needs_sync_tokens_);
-}
-
-void CompositorFrameSinkSupport::RequestCopyOfSurface(
-    std::unique_ptr<CopyOutputRequest> copy_request) {
-  if (!current_surface_id_.is_valid())
-    return;
-  Surface* current_surface =
-      surface_manager_->GetSurfaceForId(current_surface_id_);
-  current_surface->RequestCopyOfOutput(std::move(copy_request));
-  BeginFrameAck ack;
-  ack.has_damage = true;
-  if (current_surface->HasActiveFrame())
-    surface_manager_->SurfaceModified(current_surface->surface_id(), ack);
-}
-
-Surface* CompositorFrameSinkSupport::GetCurrentSurfaceForTesting() {
-  return surface_manager_->GetSurfaceForId(current_surface_id_);
-}
-
-}  // namespace cc
diff --git a/cc/surfaces/compositor_frame_sink_support.h b/cc/surfaces/compositor_frame_sink_support.h
deleted file mode 100644
index 15ee062..0000000
--- a/cc/surfaces/compositor_frame_sink_support.h
+++ /dev/null
@@ -1,162 +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_SURFACES_COMPOSITOR_FRAME_SINK_SUPPORT_H_
-#define CC_SURFACES_COMPOSITOR_FRAME_SINK_SUPPORT_H_
-
-#include <memory>
-#include <unordered_set>
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "base/memory/weak_ptr.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/frame_sink_manager_client.h"
-#include "cc/surfaces/referenced_surface_tracker.h"
-#include "cc/surfaces/surface_client.h"
-#include "cc/surfaces/surface_info.h"
-#include "cc/surfaces/surface_resource_holder.h"
-#include "cc/surfaces/surface_resource_holder_client.h"
-#include "cc/surfaces/surfaces_export.h"
-
-namespace cc {
-
-class CompositorFrameSinkSupportClient;
-class FrameSinkManager;
-class Surface;
-class SurfaceManager;
-
-class CC_SURFACES_EXPORT CompositorFrameSinkSupport
-    : public BeginFrameObserver,
-      public SurfaceResourceHolderClient,
-      public FrameSinkManagerClient,
-      public SurfaceClient {
- public:
-  static std::unique_ptr<CompositorFrameSinkSupport> Create(
-      CompositorFrameSinkSupportClient* client,
-      FrameSinkManager* frame_sink_manager,
-      const viz::FrameSinkId& frame_sink_id,
-      bool is_root,
-      bool handles_frame_sink_id_invalidation,
-      bool needs_sync_tokens);
-
-  ~CompositorFrameSinkSupport() override;
-
-  const viz::FrameSinkId& frame_sink_id() const { return frame_sink_id_; }
-
-  FrameSinkManager* frame_sink_manager() { return frame_sink_manager_; }
-  SurfaceManager* surface_manager() { return surface_manager_; }
-
-  // SurfaceClient implementation.
-  void OnSurfaceActivated(Surface* surface) override;
-  void RefResources(
-      const std::vector<TransferableResource>& resources) override;
-  void UnrefResources(const std::vector<ReturnedResource>& resources) override;
-  void ReturnResources(const std::vector<ReturnedResource>& resources) override;
-  void ReceiveFromChild(
-      const std::vector<TransferableResource>& resources) override;
-
-  // FrameSinkManagerClient implementation.
-  void SetBeginFrameSource(BeginFrameSource* begin_frame_source) override;
-
-  void EvictCurrentSurface();
-  void SetNeedsBeginFrame(bool needs_begin_frame);
-  void DidNotProduceFrame(const BeginFrameAck& ack);
-  bool SubmitCompositorFrame(const viz::LocalSurfaceId& local_surface_id,
-                             CompositorFrame frame);
-  void RequestCopyOfSurface(std::unique_ptr<CopyOutputRequest> request);
-  void ClaimTemporaryReference(const viz::SurfaceId& surface_id);
-
-  Surface* GetCurrentSurfaceForTesting();
-
- protected:
-  CompositorFrameSinkSupport(CompositorFrameSinkSupportClient* client,
-                             const viz::FrameSinkId& frame_sink_id,
-                             bool is_root,
-                             bool handles_frame_sink_id_invalidation,
-                             bool needs_sync_tokens);
-
-  void Init(FrameSinkManager* frame_sink_manager);
-
- private:
-  // Updates surface references using |active_referenced_surfaces| from the most
-  // recent CompositorFrame. This will add and remove top-level root references
-  // if |is_root_| is true and |local_surface_id| has changed. Modifies surface
-  // references stored in SurfaceManager.
-  void UpdateSurfaceReferences(
-      const viz::LocalSurfaceId& local_surface_id,
-      const std::vector<viz::SurfaceId>& active_referenced_surfaces);
-
-  // Creates a surface reference from the top-level root to |surface_id|.
-  SurfaceReference MakeTopLevelRootReference(const viz::SurfaceId& surface_id);
-
-  void DidReceiveCompositorFrameAck();
-  void WillDrawSurface(const viz::LocalSurfaceId& local_surface_id,
-                       const gfx::Rect& damage_rect);
-
-  // BeginFrameObserver implementation.
-  void OnBeginFrame(const BeginFrameArgs& args) override;
-  const BeginFrameArgs& LastUsedBeginFrameArgs() const override;
-  void OnBeginFrameSourcePausedChanged(bool paused) override;
-
-  void UpdateNeedsBeginFramesInternal();
-  Surface* CreateSurface(const SurfaceInfo& surface_info);
-
-  CompositorFrameSinkSupportClient* const client_;
-
-  FrameSinkManager* frame_sink_manager_ = nullptr;
-  SurfaceManager* surface_manager_ = nullptr;
-
-  const viz::FrameSinkId frame_sink_id_;
-  viz::SurfaceId current_surface_id_;
-
-  // If this contains a value then a surface reference from the top-level root
-  // to viz::SurfaceId(frame_sink_id_, referenced_local_surface_id_.value()) was
-  // added. This will not contain a value if |is_root_| is false.
-  base::Optional<viz::LocalSurfaceId> referenced_local_surface_id_;
-
-  SurfaceResourceHolder surface_resource_holder_;
-
-  // Counts the number of CompositorFrames that have been submitted and have not
-  // yet received an ACK.
-  int ack_pending_count_ = 0;
-  std::vector<ReturnedResource> surface_returned_resources_;
-
-  // The begin frame source being observered. Null if none.
-  BeginFrameSource* begin_frame_source_ = nullptr;
-
-  // The last begin frame args generated by the begin frame source.
-  BeginFrameArgs last_begin_frame_args_;
-
-  // Whether a request for begin frames has been issued.
-  bool needs_begin_frame_ = false;
-
-  // Whether or not a frame observer has been added.
-  bool added_frame_observer_ = false;
-
-  const bool is_root_;
-  const bool needs_sync_tokens_;
-  bool seen_first_frame_activation_ = false;
-
-  // TODO(staraz): Remove this flag once ui::Compositor no longer needs to call
-  // RegisterFrameSinkId().
-  // A surfaceSequence's validity is bound to the lifetime of the parent
-  // FrameSink that created it. We track the lifetime of FrameSinks through
-  // RegisterFrameSinkId and InvalidateFrameSinkId. During startup and GPU
-  // restart, a SurfaceSequence created by the top most layer compositor may be
-  // used prior to the creation of the associated CompositorFrameSinkSupport.
-  // CompositorFrameSinkSupport is created asynchronously when a new GPU channel
-  // is established. Once we switch to SurfaceReferences, this ordering concern
-  // goes away and we can remove this bool.
-  const bool handles_frame_sink_id_invalidation_;
-
-  base::WeakPtrFactory<CompositorFrameSinkSupport> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(CompositorFrameSinkSupport);
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_COMPOSITOR_FRAME_SINK_SUPPORT_H_
diff --git a/cc/surfaces/compositor_frame_sink_support_client.h b/cc/surfaces/compositor_frame_sink_support_client.h
deleted file mode 100644
index f0f4fb2..0000000
--- a/cc/surfaces/compositor_frame_sink_support_client.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_SURFACES_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_
-#define CC_SURFACES_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_
-
-#include "cc/resources/returned_resource.h"
-
-namespace gfx {
-class Rect;
-}
-
-namespace viz {
-class LocalSurfaceId;
-}
-
-namespace cc {
-
-struct BeginFrameArgs;
-
-class CompositorFrameSinkSupportClient {
- public:
-  // Notification that the previous CompositorFrame given to
-  // SubmitCompositorFrame() has been processed and that another frame
-  // can be submitted. This provides backpressure from the display compositor
-  // so that frames are submitted only at the rate it can handle them.
-  // TODO(fsamuel): This method ought not be necessary with unified BeginFrame.
-  // However, there's a fair amount of cleanup and refactoring necessary to get
-  // rid of it.
-  virtual void DidReceiveCompositorFrameAck(
-      const std::vector<ReturnedResource>& resources) = 0;
-
-  // Notification for the client to generate a CompositorFrame.
-  virtual void OnBeginFrame(const BeginFrameArgs& args) = 0;
-
-  // Returns resources sent to SubmitCompositorFrame to be reused or freed.
-  virtual void ReclaimResources(
-      const std::vector<ReturnedResource>& resources) = 0;
-
-  // Called when surface is being scheduled for a draw.
-  virtual void WillDrawSurface(const viz::LocalSurfaceId& local_surface_id,
-                               const gfx::Rect& damage_rect) = 0;
-
- protected:
-  virtual ~CompositorFrameSinkSupportClient() {}
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_
diff --git a/cc/surfaces/compositor_frame_sink_support_unittest.cc b/cc/surfaces/compositor_frame_sink_support_unittest.cc
deleted file mode 100644
index f1227f6..0000000
--- a/cc/surfaces/compositor_frame_sink_support_unittest.cc
+++ /dev/null
@@ -1,898 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/surfaces/compositor_frame_sink_support.h"
-
-#include "base/macros.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/copy_output_request.h"
-#include "cc/output/copy_output_result.h"
-#include "cc/resources/resource_provider.h"
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
-#include "cc/surfaces/frame_sink_manager.h"
-#include "cc/surfaces/surface_info.h"
-#include "cc/test/begin_frame_args_test.h"
-#include "cc/test/compositor_frame_helpers.h"
-#include "cc/test/fake_external_begin_frame_source.h"
-#include "cc/test/fake_surface_observer.h"
-#include "cc/test/mock_compositor_frame_sink_support_client.h"
-#include "components/viz/common/frame_sink_id.h"
-#include "components/viz/common/surface_id.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using testing::UnorderedElementsAre;
-using testing::IsEmpty;
-using testing::SizeIs;
-using testing::Invoke;
-using testing::_;
-using testing::Eq;
-
-namespace cc {
-namespace test {
-namespace {
-
-constexpr bool kIsRoot = true;
-constexpr bool kIsChildRoot = false;
-constexpr bool kHandlesFrameSinkIdInvalidation = true;
-constexpr bool kNeedsSyncPoints = true;
-
-constexpr viz::FrameSinkId kArbitraryFrameSinkId(1, 1);
-constexpr viz::FrameSinkId kAnotherArbitraryFrameSinkId(2, 2);
-constexpr viz::FrameSinkId kYetAnotherArbitraryFrameSinkId(3, 3);
-
-const base::UnguessableToken kArbitraryToken = base::UnguessableToken::Create();
-const base::UnguessableToken kArbitrarySourceId1 =
-    base::UnguessableToken::Deserialize(0xdead, 0xbeef);
-const base::UnguessableToken kArbitrarySourceId2 =
-    base::UnguessableToken::Deserialize(0xdead, 0xbee0);
-
-gpu::SyncToken GenTestSyncToken(int id) {
-  gpu::SyncToken token;
-  token.Set(gpu::CommandBufferNamespace::GPU_IO, 0,
-            gpu::CommandBufferId::FromUnsafeValue(id), 1);
-  return token;
-}
-
-class FakeCompositorFrameSinkSupportClient
-    : public CompositorFrameSinkSupportClient {
- public:
-  FakeCompositorFrameSinkSupportClient() = default;
-  ~FakeCompositorFrameSinkSupportClient() override = default;
-
-  void DidReceiveCompositorFrameAck(
-      const std::vector<ReturnedResource>& resources) override {
-    InsertResources(resources);
-  }
-
-  void OnBeginFrame(const BeginFrameArgs& args) override {}
-
-  void ReclaimResources(
-      const std::vector<ReturnedResource>& resources) override {
-    InsertResources(resources);
-  }
-
-  void WillDrawSurface(const viz::LocalSurfaceId& local_surface_id,
-                       const gfx::Rect& damage_rect) override {}
-
-  void clear_returned_resources() { returned_resources_.clear(); }
-  const std::vector<ReturnedResource>& returned_resources() {
-    return returned_resources_;
-  }
-
- private:
-  void InsertResources(const std::vector<ReturnedResource>& resources) {
-    returned_resources_.insert(returned_resources_.end(), resources.begin(),
-                               resources.end());
-  }
-
-  std::vector<ReturnedResource> returned_resources_;
-
-  DISALLOW_COPY_AND_ASSIGN(FakeCompositorFrameSinkSupportClient);
-};
-
-class CompositorFrameSinkSupportTest : public testing::Test {
- public:
-  CompositorFrameSinkSupportTest()
-      : support_(
-            CompositorFrameSinkSupport::Create(&fake_support_client_,
-                                               &manager_,
-                                               kArbitraryFrameSinkId,
-                                               kIsRoot,
-                                               kHandlesFrameSinkIdInvalidation,
-                                               kNeedsSyncPoints)),
-        begin_frame_source_(0.f, false),
-        local_surface_id_(3, kArbitraryToken),
-        frame_sync_token_(GenTestSyncToken(4)),
-        consumer_sync_token_(GenTestSyncToken(5)) {
-    manager_.surface_manager()->AddObserver(&surface_observer_);
-    support_->SetBeginFrameSource(&begin_frame_source_);
-  }
-  ~CompositorFrameSinkSupportTest() override {
-    manager_.surface_manager()->RemoveObserver(&surface_observer_);
-    support_->EvictCurrentSurface();
-  }
-
-  void SubmitCompositorFrameWithResources(ResourceId* resource_ids,
-                                          size_t num_resource_ids) {
-    CompositorFrame frame = MakeCompositorFrame();
-    for (size_t i = 0u; i < num_resource_ids; ++i) {
-      TransferableResource resource;
-      resource.id = resource_ids[i];
-      resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
-      resource.mailbox_holder.sync_token = frame_sync_token_;
-      frame.resource_list.push_back(resource);
-    }
-    support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
-    EXPECT_EQ(surface_observer_.last_created_surface_id().local_surface_id(),
-              local_surface_id_);
-  }
-
-  void UnrefResources(ResourceId* ids_to_unref,
-                      int* counts_to_unref,
-                      size_t num_ids_to_unref) {
-    std::vector<ReturnedResource> unref_array;
-    for (size_t i = 0; i < num_ids_to_unref; ++i) {
-      ReturnedResource resource;
-      resource.sync_token = consumer_sync_token_;
-      resource.id = ids_to_unref[i];
-      resource.count = counts_to_unref[i];
-      unref_array.push_back(resource);
-    }
-    support_->UnrefResources(unref_array);
-  }
-
-  void CheckReturnedResourcesMatchExpected(ResourceId* expected_returned_ids,
-                                           int* expected_returned_counts,
-                                           size_t expected_resources,
-                                           gpu::SyncToken expected_sync_token) {
-    const std::vector<ReturnedResource>& actual_resources =
-        fake_support_client_.returned_resources();
-    ASSERT_EQ(expected_resources, actual_resources.size());
-    for (size_t i = 0; i < expected_resources; ++i) {
-      ReturnedResource resource = actual_resources[i];
-      EXPECT_EQ(expected_sync_token, resource.sync_token);
-      EXPECT_EQ(expected_returned_ids[i], resource.id);
-      EXPECT_EQ(expected_returned_counts[i], resource.count);
-    }
-    fake_support_client_.clear_returned_resources();
-  }
-
-  Surface* GetSurfaceForId(const viz::SurfaceId& id) {
-    return manager_.surface_manager()->GetSurfaceForId(id);
-  }
-
-  void RefCurrentFrameResources() {
-    Surface* surface = GetSurfaceForId(
-        viz::SurfaceId(support_->frame_sink_id(), local_surface_id_));
-    support_->RefResources(surface->GetActiveFrame().resource_list);
-  }
-
- protected:
-  FrameSinkManager manager_;
-  FakeCompositorFrameSinkSupportClient fake_support_client_;
-  std::unique_ptr<CompositorFrameSinkSupport> support_;
-  FakeExternalBeginFrameSource begin_frame_source_;
-  viz::LocalSurfaceId local_surface_id_;
-  FakeSurfaceObserver surface_observer_;
-
-  // This is the sync token submitted with the frame. It should never be
-  // returned to the client.
-  const gpu::SyncToken frame_sync_token_;
-
-  // This is the sync token returned by the consumer. It should always be
-  // returned to the client.
-  const gpu::SyncToken consumer_sync_token_;
-};
-
-// Tests submitting a frame with resources followed by one with no resources
-// with no resource provider action in between.
-TEST_F(CompositorFrameSinkSupportTest, ResourceLifetimeSimple) {
-  ResourceId first_frame_ids[] = {1, 2, 3};
-  SubmitCompositorFrameWithResources(first_frame_ids,
-                                     arraysize(first_frame_ids));
-
-  // All of the resources submitted in the first frame are still in use at this
-  // time by virtue of being in the pending frame, so none can be returned to
-  // the client yet.
-  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
-  fake_support_client_.clear_returned_resources();
-
-  // The second frame references no resources of first frame and thus should
-  // make all resources of first frame available to be returned.
-  SubmitCompositorFrameWithResources(NULL, 0);
-
-  ResourceId expected_returned_ids[] = {1, 2, 3};
-  int expected_returned_counts[] = {1, 1, 1};
-  // Resources were never consumed so no sync token should be set.
-  CheckReturnedResourcesMatchExpected(
-      expected_returned_ids, expected_returned_counts,
-      arraysize(expected_returned_counts), gpu::SyncToken());
-
-  ResourceId third_frame_ids[] = {4, 5, 6};
-  SubmitCompositorFrameWithResources(third_frame_ids,
-                                     arraysize(third_frame_ids));
-
-  // All of the resources submitted in the third frame are still in use at this
-  // time by virtue of being in the pending frame, so none can be returned to
-  // the client yet.
-  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
-  fake_support_client_.clear_returned_resources();
-
-  // The forth frame references no resources of third frame and thus should
-  // make all resources of third frame available to be returned.
-  ResourceId forth_frame_ids[] = {7, 8, 9};
-  SubmitCompositorFrameWithResources(forth_frame_ids,
-                                     arraysize(forth_frame_ids));
-
-  ResourceId forth_expected_returned_ids[] = {4, 5, 6};
-  int forth_expected_returned_counts[] = {1, 1, 1};
-  // Resources were never consumed so no sync token should be set.
-  CheckReturnedResourcesMatchExpected(
-      forth_expected_returned_ids, forth_expected_returned_counts,
-      arraysize(forth_expected_returned_counts), gpu::SyncToken());
-}
-
-// Tests submitting a frame with resources followed by one with no resources
-// with the resource provider holding everything alive.
-TEST_F(CompositorFrameSinkSupportTest,
-       ResourceLifetimeSimpleWithProviderHoldingAlive) {
-  ResourceId first_frame_ids[] = {1, 2, 3};
-  SubmitCompositorFrameWithResources(first_frame_ids,
-                                     arraysize(first_frame_ids));
-
-  // All of the resources submitted in the first frame are still in use at this
-  // time by virtue of being in the pending frame, so none can be returned to
-  // the client yet.
-  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
-  fake_support_client_.clear_returned_resources();
-
-  // Hold on to everything.
-  RefCurrentFrameResources();
-
-  // The second frame references no resources and thus should make all resources
-  // available to be returned as soon as the resource provider releases them.
-  SubmitCompositorFrameWithResources(NULL, 0);
-
-  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
-  fake_support_client_.clear_returned_resources();
-
-  int release_counts[] = {1, 1, 1};
-  UnrefResources(first_frame_ids, release_counts, arraysize(first_frame_ids));
-
-  // None is returned to the client since DidReceiveCompositorAck is not
-  // invoked.
-  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
-
-  // Submitting an empty frame causes previous resources referenced by the
-  // previous frame to be returned to client.
-  SubmitCompositorFrameWithResources(nullptr, 0);
-  ResourceId expected_returned_ids[] = {1, 2, 3};
-  int expected_returned_counts[] = {1, 1, 1};
-  CheckReturnedResourcesMatchExpected(
-      expected_returned_ids, expected_returned_counts,
-      arraysize(expected_returned_counts), consumer_sync_token_);
-}
-
-// Tests referencing a resource, unref'ing it to zero, then using it again
-// before returning it to the client.
-TEST_F(CompositorFrameSinkSupportTest, ResourceReusedBeforeReturn) {
-  ResourceId first_frame_ids[] = {7};
-  SubmitCompositorFrameWithResources(first_frame_ids,
-                                     arraysize(first_frame_ids));
-
-  // This removes all references to resource id 7.
-  SubmitCompositorFrameWithResources(NULL, 0);
-
-  // This references id 7 again.
-  SubmitCompositorFrameWithResources(first_frame_ids,
-                                     arraysize(first_frame_ids));
-
-  // This removes it again.
-  SubmitCompositorFrameWithResources(NULL, 0);
-
-  // Now it should be returned.
-  // We don't care how many entries are in the returned array for 7, so long as
-  // the total returned count matches the submitted count.
-  const std::vector<ReturnedResource>& returned =
-      fake_support_client_.returned_resources();
-  size_t return_count = 0;
-  for (size_t i = 0; i < returned.size(); ++i) {
-    EXPECT_EQ(7u, returned[i].id);
-    return_count += returned[i].count;
-  }
-  EXPECT_EQ(2u, return_count);
-}
-
-// Tests having resources referenced multiple times, as if referenced by
-// multiple providers.
-TEST_F(CompositorFrameSinkSupportTest, ResourceRefMultipleTimes) {
-  ResourceId first_frame_ids[] = {3, 4};
-  SubmitCompositorFrameWithResources(first_frame_ids,
-                                     arraysize(first_frame_ids));
-
-  // Ref resources from the first frame twice.
-  RefCurrentFrameResources();
-  RefCurrentFrameResources();
-
-  ResourceId second_frame_ids[] = {4, 5};
-  SubmitCompositorFrameWithResources(second_frame_ids,
-                                     arraysize(second_frame_ids));
-
-  // Ref resources from the second frame 3 times.
-  RefCurrentFrameResources();
-  RefCurrentFrameResources();
-  RefCurrentFrameResources();
-
-  // Submit a frame with no resources to remove all current frame refs from
-  // submitted resources.
-  SubmitCompositorFrameWithResources(NULL, 0);
-
-  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
-  fake_support_client_.clear_returned_resources();
-
-  // Expected current refs:
-  //  3 -> 2
-  //  4 -> 2 + 3 = 5
-  //  5 -> 3
-  {
-    SCOPED_TRACE("unref all 3");
-    ResourceId ids_to_unref[] = {3, 4, 5};
-    int counts[] = {1, 1, 1};
-    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
-
-    EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
-    fake_support_client_.clear_returned_resources();
-
-    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
-    SubmitCompositorFrameWithResources(nullptr, 0);
-    ResourceId expected_returned_ids[] = {3};
-    int expected_returned_counts[] = {1};
-    CheckReturnedResourcesMatchExpected(
-        expected_returned_ids, expected_returned_counts,
-        arraysize(expected_returned_counts), consumer_sync_token_);
-  }
-
-  // Expected refs remaining:
-  //  4 -> 3
-  //  5 -> 1
-  {
-    SCOPED_TRACE("unref 4 and 5");
-    ResourceId ids_to_unref[] = {4, 5};
-    int counts[] = {1, 1};
-    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
-    SubmitCompositorFrameWithResources(nullptr, 0);
-
-    ResourceId expected_returned_ids[] = {5};
-    int expected_returned_counts[] = {1};
-    CheckReturnedResourcesMatchExpected(
-        expected_returned_ids, expected_returned_counts,
-        arraysize(expected_returned_counts), consumer_sync_token_);
-  }
-
-  // Now, just 2 refs remaining on resource 4. Unref both at once and make sure
-  // the returned count is correct.
-  {
-    SCOPED_TRACE("unref only 4");
-    ResourceId ids_to_unref[] = {4};
-    int counts[] = {2};
-    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
-    SubmitCompositorFrameWithResources(nullptr, 0);
-
-    ResourceId expected_returned_ids[] = {4};
-    int expected_returned_counts[] = {2};
-    CheckReturnedResourcesMatchExpected(
-        expected_returned_ids, expected_returned_counts,
-        arraysize(expected_returned_counts), consumer_sync_token_);
-  }
-}
-
-TEST_F(CompositorFrameSinkSupportTest, ResourceLifetime) {
-  ResourceId first_frame_ids[] = {1, 2, 3};
-  SubmitCompositorFrameWithResources(first_frame_ids,
-                                     arraysize(first_frame_ids));
-
-  // All of the resources submitted in the first frame are still in use at this
-  // time by virtue of being in the pending frame, so none can be returned to
-  // the client yet.
-  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
-  fake_support_client_.clear_returned_resources();
-
-  // The second frame references some of the same resources, but some different
-  // ones. We expect to receive back resource 1 with a count of 1 since it was
-  // only referenced by the first frame.
-  ResourceId second_frame_ids[] = {2, 3, 4};
-  SubmitCompositorFrameWithResources(second_frame_ids,
-                                     arraysize(second_frame_ids));
-  {
-    SCOPED_TRACE("second frame");
-    ResourceId expected_returned_ids[] = {1};
-    int expected_returned_counts[] = {1};
-    CheckReturnedResourcesMatchExpected(
-        expected_returned_ids, expected_returned_counts,
-        arraysize(expected_returned_counts), gpu::SyncToken());
-  }
-
-  // The third frame references a disjoint set of resources, so we expect to
-  // receive back all resources from the first and second frames. Resource IDs 2
-  // and 3 will have counts of 2, since they were used in both frames, and
-  // resource ID 4 will have a count of 1.
-  ResourceId third_frame_ids[] = {10, 11, 12, 13};
-  SubmitCompositorFrameWithResources(third_frame_ids,
-                                     arraysize(third_frame_ids));
-
-  {
-    SCOPED_TRACE("third frame");
-    ResourceId expected_returned_ids[] = {2, 3, 4};
-    int expected_returned_counts[] = {2, 2, 1};
-    CheckReturnedResourcesMatchExpected(
-        expected_returned_ids, expected_returned_counts,
-        arraysize(expected_returned_counts), gpu::SyncToken());
-  }
-
-  // Simulate a ResourceProvider taking a ref on all of the resources.
-  RefCurrentFrameResources();
-
-  ResourceId fourth_frame_ids[] = {12, 13};
-  SubmitCompositorFrameWithResources(fourth_frame_ids,
-                                     arraysize(fourth_frame_ids));
-
-  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
-
-  RefCurrentFrameResources();
-
-  // All resources are still being used by the external reference, so none can
-  // be returned to the client.
-  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
-
-  // Release resources associated with the first RefCurrentFrameResources() call
-  // first.
-  {
-    ResourceId ids_to_unref[] = {10, 11, 12, 13};
-    int counts[] = {1, 1, 1, 1};
-    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
-  }
-
-  // Nothing is returned to the client yet since DidReceiveCompositorFrameAck
-  // is not invoked.
-  {
-    SCOPED_TRACE("fourth frame, first unref");
-    CheckReturnedResourcesMatchExpected(nullptr, nullptr, 0,
-                                        consumer_sync_token_);
-  }
-
-  {
-    ResourceId ids_to_unref[] = {12, 13};
-    int counts[] = {1, 1};
-    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
-  }
-
-  // Resources 12 and 13 are still in use by the current frame, so they
-  // shouldn't be available to be returned.
-  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
-
-  // If we submit an empty frame, however, they should become available.
-  // Resources that were previously unref'd also return at this point.
-  SubmitCompositorFrameWithResources(NULL, 0u);
-
-  {
-    SCOPED_TRACE("fourth frame, second unref");
-    ResourceId expected_returned_ids[] = {10, 11, 12, 13};
-    int expected_returned_counts[] = {1, 1, 2, 2};
-    CheckReturnedResourcesMatchExpected(
-        expected_returned_ids, expected_returned_counts,
-        arraysize(expected_returned_counts), consumer_sync_token_);
-  }
-}
-
-TEST_F(CompositorFrameSinkSupportTest, AddDuringEviction) {
-  MockCompositorFrameSinkSupportClient mock_client;
-  std::unique_ptr<CompositorFrameSinkSupport> support =
-      CompositorFrameSinkSupport::Create(
-          &mock_client, &manager_, kAnotherArbitraryFrameSinkId, kIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId local_surface_id(6, kArbitraryToken);
-  support->SubmitCompositorFrame(local_surface_id, MakeCompositorFrame());
-
-  EXPECT_CALL(mock_client, DidReceiveCompositorFrameAck(_))
-      .WillOnce(testing::InvokeWithoutArgs([&support, &mock_client]() {
-        viz::LocalSurfaceId new_id(7, base::UnguessableToken::Create());
-        support->SubmitCompositorFrame(new_id, MakeCompositorFrame());
-      }))
-      .WillRepeatedly(testing::Return());
-  support->EvictCurrentSurface();
-}
-
-// Tests doing an EvictCurrentSurface before shutting down the factory.
-TEST_F(CompositorFrameSinkSupportTest, EvictCurrentSurface) {
-  MockCompositorFrameSinkSupportClient mock_client;
-  std::unique_ptr<CompositorFrameSinkSupport> support =
-      CompositorFrameSinkSupport::Create(
-          &mock_client, &manager_, kAnotherArbitraryFrameSinkId, kIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId local_surface_id(7, kArbitraryToken);
-  viz::SurfaceId id(kAnotherArbitraryFrameSinkId, local_surface_id);
-
-  TransferableResource resource;
-  resource.id = 1;
-  resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
-  CompositorFrame frame = MakeCompositorFrame();
-  frame.resource_list.push_back(resource);
-  support->SubmitCompositorFrame(local_surface_id, std::move(frame));
-  EXPECT_EQ(surface_observer_.last_created_surface_id().local_surface_id(),
-            local_surface_id);
-  local_surface_id_ = viz::LocalSurfaceId();
-
-  std::vector<ReturnedResource> returned_resources = {
-      resource.ToReturnedResource()};
-  EXPECT_TRUE(GetSurfaceForId(id));
-  EXPECT_CALL(mock_client, DidReceiveCompositorFrameAck(returned_resources))
-      .Times(1);
-  support->EvictCurrentSurface();
-  EXPECT_FALSE(GetSurfaceForId(id));
-}
-
-// Tests doing an EvictCurrentSurface which has unregistered dependency.
-TEST_F(CompositorFrameSinkSupportTest,
-       EvictCurrentSurfaceDependencyUnRegistered) {
-  MockCompositorFrameSinkSupportClient mock_client;
-  std::unique_ptr<CompositorFrameSinkSupport> support =
-      CompositorFrameSinkSupport::Create(
-          &mock_client, &manager_, kAnotherArbitraryFrameSinkId, kIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId local_surface_id(7, kArbitraryToken);
-
-  TransferableResource resource;
-  resource.id = 1;
-  resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
-  CompositorFrame frame = MakeCompositorFrame();
-  frame.resource_list.push_back(resource);
-  support->SubmitCompositorFrame(local_surface_id, std::move(frame));
-  EXPECT_EQ(surface_observer_.last_created_surface_id().local_surface_id(),
-            local_surface_id);
-  local_surface_id_ = viz::LocalSurfaceId();
-
-  viz::SurfaceId surface_id(kAnotherArbitraryFrameSinkId, local_surface_id);
-  Surface* surface = GetSurfaceForId(surface_id);
-  surface->AddDestructionDependency(
-      SurfaceSequence(kYetAnotherArbitraryFrameSinkId, 4));
-
-  std::vector<ReturnedResource> returned_resource = {
-      resource.ToReturnedResource()};
-
-  EXPECT_TRUE(GetSurfaceForId(surface_id));
-  EXPECT_CALL(mock_client, DidReceiveCompositorFrameAck(returned_resource))
-      .Times(1);
-  support->EvictCurrentSurface();
-  EXPECT_FALSE(GetSurfaceForId(surface_id));
-}
-
-// Tests doing an EvictCurrentSurface which has registered dependency.
-TEST_F(CompositorFrameSinkSupportTest,
-       EvictCurrentSurfaceDependencyRegistered) {
-  MockCompositorFrameSinkSupportClient mock_client;
-  std::unique_ptr<CompositorFrameSinkSupport> support =
-      CompositorFrameSinkSupport::Create(
-          &mock_client, &manager_, kAnotherArbitraryFrameSinkId, kIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId local_surface_id(7, kArbitraryToken);
-
-  TransferableResource resource;
-  resource.id = 1;
-  resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
-  CompositorFrame frame = MakeCompositorFrame();
-  frame.resource_list.push_back(resource);
-  uint32_t execute_count = 0;
-  support->SubmitCompositorFrame(local_surface_id, std::move(frame));
-  EXPECT_EQ(surface_observer_.last_created_surface_id().local_surface_id(),
-            local_surface_id);
-  local_surface_id_ = viz::LocalSurfaceId();
-
-  manager_.RegisterFrameSinkId(kYetAnotherArbitraryFrameSinkId);
-
-  viz::SurfaceId surface_id(kAnotherArbitraryFrameSinkId, local_surface_id);
-  Surface* surface = GetSurfaceForId(surface_id);
-  surface->AddDestructionDependency(
-      SurfaceSequence(kYetAnotherArbitraryFrameSinkId, 4));
-
-  std::vector<ReturnedResource> returned_resources;
-  EXPECT_TRUE(GetSurfaceForId(surface_id));
-  support->EvictCurrentSurface();
-  EXPECT_TRUE(GetSurfaceForId(surface_id));
-  EXPECT_EQ(0u, execute_count);
-
-  returned_resources.push_back(resource.ToReturnedResource());
-  EXPECT_CALL(mock_client, DidReceiveCompositorFrameAck(returned_resources))
-      .Times(1);
-  manager_.surface_manager()->SatisfySequence(
-      SurfaceSequence(kYetAnotherArbitraryFrameSinkId, 4));
-  EXPECT_FALSE(GetSurfaceForId(surface_id));
-}
-
-TEST_F(CompositorFrameSinkSupportTest, DestroySequence) {
-  viz::LocalSurfaceId local_surface_id2(5, kArbitraryToken);
-  std::unique_ptr<CompositorFrameSinkSupport> support2 =
-      CompositorFrameSinkSupport::Create(
-          &fake_support_client_, &manager_, kYetAnotherArbitraryFrameSinkId,
-          kIsChildRoot, kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::SurfaceId id2(kYetAnotherArbitraryFrameSinkId, local_surface_id2);
-  support2->SubmitCompositorFrame(local_surface_id2, MakeCompositorFrame());
-
-  // Check that waiting before the sequence is satisfied works.
-  GetSurfaceForId(id2)->AddDestructionDependency(
-      SurfaceSequence(kYetAnotherArbitraryFrameSinkId, 4));
-  support2->EvictCurrentSurface();
-
-  DCHECK(GetSurfaceForId(id2));
-  manager_.surface_manager()->SatisfySequence(
-      SurfaceSequence(kYetAnotherArbitraryFrameSinkId, 4));
-  manager_.surface_manager()->SatisfySequence(
-      SurfaceSequence(kYetAnotherArbitraryFrameSinkId, 6));
-  DCHECK(!GetSurfaceForId(id2));
-
-  // Check that waiting after the sequence is satisfied works.
-  support2->SubmitCompositorFrame(local_surface_id2, MakeCompositorFrame());
-  DCHECK(GetSurfaceForId(id2));
-  GetSurfaceForId(id2)->AddDestructionDependency(
-      SurfaceSequence(kAnotherArbitraryFrameSinkId, 6));
-  support2->EvictCurrentSurface();
-  DCHECK(!GetSurfaceForId(id2));
-}
-
-// Tests that Surface ID namespace invalidation correctly allows
-// Sequences to be ignored.
-TEST_F(CompositorFrameSinkSupportTest, InvalidFrameSinkId) {
-  viz::FrameSinkId frame_sink_id(1234, 5678);
-
-  viz::LocalSurfaceId local_surface_id(5, kArbitraryToken);
-  viz::SurfaceId id(support_->frame_sink_id(), local_surface_id);
-  support_->SubmitCompositorFrame(local_surface_id, MakeCompositorFrame());
-
-  manager_.RegisterFrameSinkId(frame_sink_id);
-  GetSurfaceForId(id)->AddDestructionDependency(
-      SurfaceSequence(frame_sink_id, 4));
-
-  support_->EvictCurrentSurface();
-
-  // Verify the dependency has prevented the surface from getting destroyed.
-  EXPECT_TRUE(GetSurfaceForId(id));
-
-  manager_.InvalidateFrameSinkId(frame_sink_id);
-
-  // Verify that the invalidated namespace caused the unsatisfied sequence
-  // to be ignored.
-  EXPECT_FALSE(GetSurfaceForId(id));
-}
-
-TEST_F(CompositorFrameSinkSupportTest, DestroyCycle) {
-  viz::LocalSurfaceId local_surface_id2(5, kArbitraryToken);
-  viz::SurfaceId id2(kYetAnotherArbitraryFrameSinkId, local_surface_id2);
-  std::unique_ptr<CompositorFrameSinkSupport> support2 =
-      CompositorFrameSinkSupport::Create(
-          &fake_support_client_, &manager_, kYetAnotherArbitraryFrameSinkId,
-          kIsChildRoot, kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  manager_.RegisterFrameSinkId(kAnotherArbitraryFrameSinkId);
-  // Give local_surface_id_ an initial frame so another client can refer to
-  // that surface.
-  {
-    CompositorFrame frame = MakeCompositorFrame();
-    support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
-  }
-  // Give id2 a frame that references local_surface_id_.
-  {
-    CompositorFrame frame = MakeCompositorFrame();
-    frame.metadata.referenced_surfaces.push_back(
-        viz::SurfaceId(support_->frame_sink_id(), local_surface_id_));
-    support2->SubmitCompositorFrame(local_surface_id2, std::move(frame));
-    EXPECT_EQ(surface_observer_.last_created_surface_id().local_surface_id(),
-              local_surface_id2);
-  }
-  GetSurfaceForId(id2)->AddDestructionDependency(
-      SurfaceSequence(kAnotherArbitraryFrameSinkId, 4));
-  support2->EvictCurrentSurface();
-  // Give local_surface_id_ a frame that references id2.
-  {
-    CompositorFrame frame = MakeCompositorFrame();
-    frame.metadata.referenced_surfaces.push_back(id2);
-    support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
-  }
-  support_->EvictCurrentSurface();
-  EXPECT_TRUE(GetSurfaceForId(id2));
-  // local_surface_id_ should be retained by reference from id2.
-  EXPECT_TRUE(GetSurfaceForId(
-      viz::SurfaceId(support_->frame_sink_id(), local_surface_id_)));
-
-  // Satisfy last destruction dependency for id2.
-  manager_.surface_manager()->SatisfySequence(
-      SurfaceSequence(kAnotherArbitraryFrameSinkId, 4));
-
-  // id2 and local_surface_id_ are in a reference cycle that has no surface
-  // sequences holding on to it, so they should be destroyed.
-  EXPECT_TRUE(!GetSurfaceForId(id2));
-  EXPECT_TRUE(!GetSurfaceForId(
-      viz::SurfaceId(support_->frame_sink_id(), local_surface_id_)));
-
-  local_surface_id_ = viz::LocalSurfaceId();
-}
-
-void CopyRequestTestCallback(bool* called,
-                             std::unique_ptr<CopyOutputResult> result) {
-  *called = true;
-}
-
-TEST_F(CompositorFrameSinkSupportTest, DuplicateCopyRequest) {
-  {
-    CompositorFrame frame = MakeCompositorFrame();
-    frame.metadata.referenced_surfaces.push_back(
-        viz::SurfaceId(support_->frame_sink_id(), local_surface_id_));
-    support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
-    EXPECT_EQ(surface_observer_.last_created_surface_id().local_surface_id(),
-              local_surface_id_);
-  }
-
-  bool called1 = false;
-  std::unique_ptr<CopyOutputRequest> request;
-  request = CopyOutputRequest::CreateRequest(
-      base::Bind(&CopyRequestTestCallback, &called1));
-  request->set_source(kArbitrarySourceId1);
-
-  support_->RequestCopyOfSurface(std::move(request));
-  EXPECT_FALSE(called1);
-
-  bool called2 = false;
-  request = CopyOutputRequest::CreateRequest(
-      base::Bind(&CopyRequestTestCallback, &called2));
-  request->set_source(kArbitrarySourceId2);
-
-  support_->RequestCopyOfSurface(std::move(request));
-  // Callbacks have different sources so neither should be called.
-  EXPECT_FALSE(called1);
-  EXPECT_FALSE(called2);
-
-  bool called3 = false;
-  request = CopyOutputRequest::CreateRequest(
-      base::Bind(&CopyRequestTestCallback, &called3));
-  request->set_source(kArbitrarySourceId1);
-
-  support_->RequestCopyOfSurface(std::move(request));
-  // Two callbacks are from source1, so the first should be called.
-  EXPECT_TRUE(called1);
-  EXPECT_FALSE(called2);
-  EXPECT_FALSE(called3);
-
-  support_->EvictCurrentSurface();
-  local_surface_id_ = viz::LocalSurfaceId();
-  EXPECT_TRUE(called1);
-  EXPECT_TRUE(called2);
-  EXPECT_TRUE(called3);
-}
-
-// Check whether the SurfaceInfo object is created and populated correctly
-// after the frame submission.
-TEST_F(CompositorFrameSinkSupportTest, SurfaceInfo) {
-  CompositorFrame frame = MakeCompositorFrame();
-
-  auto render_pass = RenderPass::Create();
-  render_pass->SetNew(1, gfx::Rect(5, 6), gfx::Rect(), gfx::Transform());
-  frame.render_pass_list.push_back(std::move(render_pass));
-
-  render_pass = RenderPass::Create();
-  render_pass->SetNew(2, gfx::Rect(7, 8), gfx::Rect(), gfx::Transform());
-  frame.render_pass_list.push_back(std::move(render_pass));
-
-  frame.metadata.device_scale_factor = 2.5f;
-
-  support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
-  viz::SurfaceId expected_surface_id(support_->frame_sink_id(),
-                                     local_surface_id_);
-  EXPECT_EQ(expected_surface_id, surface_observer_.last_surface_info().id());
-  EXPECT_EQ(2.5f, surface_observer_.last_surface_info().device_scale_factor());
-  EXPECT_EQ(gfx::Size(7, 8),
-            surface_observer_.last_surface_info().size_in_pixels());
-}
-
-// Check that if a CompositorFrame is received with size zero, we don't create
-// a Surface for it.
-TEST_F(CompositorFrameSinkSupportTest, ZeroFrameSize) {
-  viz::SurfaceId id(support_->frame_sink_id(), local_surface_id_);
-  CompositorFrame frame = MakeEmptyCompositorFrame();
-  frame.render_pass_list.push_back(RenderPass::Create());
-  EXPECT_TRUE(
-      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)));
-  EXPECT_FALSE(GetSurfaceForId(id));
-}
-
-// Check that if a CompositorFrame is received with device scale factor of 0, we
-// don't create a Surface for it.
-TEST_F(CompositorFrameSinkSupportTest, ZeroDeviceScaleFactor) {
-  viz::SurfaceId id(support_->frame_sink_id(), local_surface_id_);
-  CompositorFrame frame = MakeCompositorFrame();
-  frame.metadata.device_scale_factor = 0.f;
-  EXPECT_TRUE(
-      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)));
-  EXPECT_FALSE(GetSurfaceForId(id));
-}
-
-// Check that if the size of a CompositorFrame doesn't match the size of the
-// Surface it's being submitted to, we skip the frame.
-TEST_F(CompositorFrameSinkSupportTest, FrameSizeMismatch) {
-  viz::SurfaceId id(support_->frame_sink_id(), local_surface_id_);
-
-  // Submit a frame with size (5,5).
-  CompositorFrame frame = MakeEmptyCompositorFrame();
-  auto pass = RenderPass::Create();
-  pass->SetNew(1, gfx::Rect(5, 5), gfx::Rect(), gfx::Transform());
-  frame.render_pass_list.push_back(std::move(pass));
-  EXPECT_TRUE(
-      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)));
-  EXPECT_TRUE(GetSurfaceForId(id));
-
-  // Submit a frame with size (5,4). This frame should be rejected and the
-  // surface should be destroyed.
-  frame = MakeEmptyCompositorFrame();
-  pass = RenderPass::Create();
-  pass->SetNew(1, gfx::Rect(5, 4), gfx::Rect(), gfx::Transform());
-  frame.render_pass_list.push_back(std::move(pass));
-  EXPECT_FALSE(
-      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)));
-  EXPECT_FALSE(GetSurfaceForId(id));
-}
-
-// Check that if the device scale factor of a CompositorFrame doesn't match the
-// device scale factor of the Surface it's being submitted to, the frame is
-// rejected and the surface is destroyed.
-TEST_F(CompositorFrameSinkSupportTest, DeviceScaleFactorMismatch) {
-  viz::SurfaceId id(support_->frame_sink_id(), local_surface_id_);
-
-  // Submit a frame with device scale factor of 0.5.
-  CompositorFrame frame = MakeCompositorFrame();
-  frame.metadata.device_scale_factor = 0.5f;
-  EXPECT_TRUE(
-      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)));
-  EXPECT_TRUE(GetSurfaceForId(id));
-
-  // Submit a frame with device scale factor of 0.4. This frame should be
-  // rejected and the surface should be destroyed.
-  frame = MakeCompositorFrame();
-  frame.metadata.device_scale_factor = 0.4f;
-  EXPECT_FALSE(
-      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)));
-  EXPECT_FALSE(GetSurfaceForId(id));
-}
-
-TEST_F(CompositorFrameSinkSupportTest, PassesOnBeginFrameAcks) {
-  // Request BeginFrames.
-  support_->SetNeedsBeginFrame(true);
-
-  // Issue a BeginFrame.
-  BeginFrameArgs args =
-      CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
-  begin_frame_source_.TestOnBeginFrame(args);
-
-  // Check that the support and SurfaceManager forward the BeginFrameAck
-  // attached to a CompositorFrame to the SurfaceObserver.
-  BeginFrameAck ack(0, 1, 1, true);
-  CompositorFrame frame = MakeCompositorFrame();
-  frame.metadata.begin_frame_ack = ack;
-  support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
-  EXPECT_EQ(ack, surface_observer_.last_ack());
-
-  // Issue another BeginFrame.
-  args = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2);
-  begin_frame_source_.TestOnBeginFrame(args);
-
-  // Check that the support and SurfaceManager forward a DidNotProduceFrame ack
-  // to the SurfaceObserver.
-  BeginFrameAck ack2(0, 2, 2, false);
-  support_->DidNotProduceFrame(ack2);
-  EXPECT_EQ(ack2, surface_observer_.last_ack());
-
-  support_->SetNeedsBeginFrame(false);
-}
-
-}  // namespace
-
-}  // namespace test
-
-}  // namespace cc
diff --git a/cc/surfaces/direct_layer_tree_frame_sink.cc b/cc/surfaces/direct_layer_tree_frame_sink.cc
deleted file mode 100644
index b617cdd..0000000
--- a/cc/surfaces/direct_layer_tree_frame_sink.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/surfaces/direct_layer_tree_frame_sink.h"
-
-#include "base/bind.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/layer_tree_frame_sink_client.h"
-#include "cc/surfaces/display.h"
-#include "cc/surfaces/frame_sink_manager.h"
-#include "cc/surfaces/surface.h"
-#include "components/viz/common/frame_sink_id.h"
-#include "components/viz/common/local_surface_id_allocator.h"
-
-namespace cc {
-
-DirectLayerTreeFrameSink::DirectLayerTreeFrameSink(
-    const viz::FrameSinkId& frame_sink_id,
-    FrameSinkManager* frame_sink_manager,
-    Display* display,
-    scoped_refptr<ContextProvider> context_provider,
-    scoped_refptr<ContextProvider> worker_context_provider,
-    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-    viz::SharedBitmapManager* shared_bitmap_manager)
-    : LayerTreeFrameSink(std::move(context_provider),
-                         std::move(worker_context_provider),
-                         gpu_memory_buffer_manager,
-                         shared_bitmap_manager),
-      frame_sink_id_(frame_sink_id),
-      frame_sink_manager_(frame_sink_manager),
-      display_(display) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  capabilities_.must_always_swap = true;
-  // Display and DirectLayerTreeFrameSink share a GL context, so sync
-  // points aren't needed when passing resources between them.
-  capabilities_.delegated_sync_points_required = false;
-}
-
-DirectLayerTreeFrameSink::DirectLayerTreeFrameSink(
-    const viz::FrameSinkId& frame_sink_id,
-    FrameSinkManager* frame_sink_manager,
-    Display* display,
-    scoped_refptr<VulkanContextProvider> vulkan_context_provider)
-    : LayerTreeFrameSink(std::move(vulkan_context_provider)),
-      frame_sink_id_(frame_sink_id),
-      frame_sink_manager_(frame_sink_manager),
-      display_(display) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  capabilities_.must_always_swap = true;
-}
-
-DirectLayerTreeFrameSink::~DirectLayerTreeFrameSink() {
-  DCHECK(thread_checker_.CalledOnValidThread());
-}
-
-bool DirectLayerTreeFrameSink::BindToClient(LayerTreeFrameSinkClient* client) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-
-  if (!LayerTreeFrameSink::BindToClient(client))
-    return false;
-
-  // We want the Display's output surface to hear about lost context, and since
-  // this shares a context with it, we should not be listening for lost context
-  // callbacks on the context here.
-  if (auto* cp = context_provider())
-    cp->SetLostContextCallback(base::Closure());
-
-  constexpr bool is_root = true;
-  constexpr bool handles_frame_sink_id_invalidation = false;
-  support_ = CompositorFrameSinkSupport::Create(
-      this, frame_sink_manager_, frame_sink_id_, is_root,
-      handles_frame_sink_id_invalidation,
-      capabilities_.delegated_sync_points_required);
-  begin_frame_source_ = base::MakeUnique<ExternalBeginFrameSource>(this);
-  client_->SetBeginFrameSource(begin_frame_source_.get());
-
-  // Avoid initializing GL context here, as this should be sharing the
-  // Display's context.
-  display_->Initialize(this, frame_sink_manager_->surface_manager());
-  return true;
-}
-
-void DirectLayerTreeFrameSink::DetachFromClient() {
-  client_->SetBeginFrameSource(nullptr);
-  begin_frame_source_.reset();
-
-  // Unregister the SurfaceFactoryClient here instead of the dtor so that only
-  // one client is alive for this namespace at any given time.
-  support_.reset();
-
-  LayerTreeFrameSink::DetachFromClient();
-}
-
-void DirectLayerTreeFrameSink::SubmitCompositorFrame(CompositorFrame frame) {
-  DCHECK(frame.metadata.begin_frame_ack.has_damage);
-  DCHECK_LE(BeginFrameArgs::kStartingFrameNumber,
-            frame.metadata.begin_frame_ack.sequence_number);
-
-  gfx::Size frame_size = frame.render_pass_list.back()->output_rect.size();
-  if (!local_surface_id_.is_valid() || frame_size != last_swap_frame_size_ ||
-      frame.metadata.device_scale_factor != device_scale_factor_) {
-    local_surface_id_ = local_surface_id_allocator_.GenerateId();
-    last_swap_frame_size_ = frame_size;
-    device_scale_factor_ = frame.metadata.device_scale_factor;
-    display_->SetLocalSurfaceId(local_surface_id_, device_scale_factor_);
-  }
-
-  bool result =
-      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
-  DCHECK(result);
-}
-
-void DirectLayerTreeFrameSink::DidNotProduceFrame(const BeginFrameAck& ack) {
-  DCHECK(!ack.has_damage);
-  DCHECK_LE(BeginFrameArgs::kStartingFrameNumber, ack.sequence_number);
-  support_->DidNotProduceFrame(ack);
-}
-
-void DirectLayerTreeFrameSink::DisplayOutputSurfaceLost() {
-  is_lost_ = true;
-  client_->DidLoseLayerTreeFrameSink();
-}
-
-void DirectLayerTreeFrameSink::DisplayWillDrawAndSwap(
-    bool will_draw_and_swap,
-    const RenderPassList& render_passes) {
-  // This notification is not relevant to our client outside of tests.
-}
-
-void DirectLayerTreeFrameSink::DisplayDidDrawAndSwap() {
-  // This notification is not relevant to our client outside of tests. We
-  // unblock the client from DidDrawCallback() when the surface is going to
-  // be drawn.
-}
-
-void DirectLayerTreeFrameSink::DidReceiveCompositorFrameAck(
-    const std::vector<ReturnedResource>& resources) {
-  client_->ReclaimResources(resources);
-  client_->DidReceiveCompositorFrameAck();
-}
-
-void DirectLayerTreeFrameSink::OnBeginFrame(const BeginFrameArgs& args) {
-  begin_frame_source_->OnBeginFrame(args);
-}
-
-void DirectLayerTreeFrameSink::ReclaimResources(
-    const std::vector<ReturnedResource>& resources) {
-  client_->ReclaimResources(resources);
-}
-
-void DirectLayerTreeFrameSink::WillDrawSurface(
-    const viz::LocalSurfaceId& local_surface_id,
-    const gfx::Rect& damage_rect) {
-  // TODO(staraz): Implement this.
-}
-
-void DirectLayerTreeFrameSink::OnNeedsBeginFrames(bool needs_begin_frame) {
-  support_->SetNeedsBeginFrame(needs_begin_frame);
-}
-
-}  // namespace cc
diff --git a/cc/surfaces/direct_layer_tree_frame_sink.h b/cc/surfaces/direct_layer_tree_frame_sink.h
deleted file mode 100644
index 614b2b1..0000000
--- a/cc/surfaces/direct_layer_tree_frame_sink.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_SURFACES_DIRECT_LAYER_TREE_FRAME_SINK_H_
-#define CC_SURFACES_DIRECT_LAYER_TREE_FRAME_SINK_H_
-
-#include "base/macros.h"
-#include "base/threading/thread_checker.h"
-#include "cc/output/layer_tree_frame_sink.h"
-#include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
-#include "cc/surfaces/display_client.h"
-#include "cc/surfaces/surfaces_export.h"
-#include "components/viz/common/local_surface_id_allocator.h"
-
-namespace viz {
-class LocalSurfaceIdAllocator;
-}
-
-namespace cc {
-class Display;
-class FrameSinkManager;
-
-// This class submits compositor frames to an in-process Display, with the
-// client's frame being the root surface of the Display.
-class CC_SURFACES_EXPORT DirectLayerTreeFrameSink
-    : public LayerTreeFrameSink,
-      public NON_EXPORTED_BASE(CompositorFrameSinkSupportClient),
-      public ExternalBeginFrameSourceClient,
-      public NON_EXPORTED_BASE(DisplayClient) {
- public:
-  // The underlying Display, FrameSinkManager, and viz::LocalSurfaceIdAllocator
-  // must outlive this class.
-  DirectLayerTreeFrameSink(
-      const viz::FrameSinkId& frame_sink_id,
-      FrameSinkManager* frame_sink_manager,
-      Display* display,
-      scoped_refptr<ContextProvider> context_provider,
-      scoped_refptr<ContextProvider> worker_context_provider,
-      gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-      viz::SharedBitmapManager* shared_bitmap_manager);
-  DirectLayerTreeFrameSink(
-      const viz::FrameSinkId& frame_sink_id,
-      FrameSinkManager* frame_sink_manager,
-      Display* display,
-      scoped_refptr<VulkanContextProvider> vulkan_context_provider);
-  ~DirectLayerTreeFrameSink() override;
-
-  // LayerTreeFrameSink implementation.
-  bool BindToClient(LayerTreeFrameSinkClient* client) override;
-  void DetachFromClient() override;
-  void SubmitCompositorFrame(CompositorFrame frame) override;
-  void DidNotProduceFrame(const BeginFrameAck& ack) override;
-
-  // DisplayClient implementation.
-  void DisplayOutputSurfaceLost() override;
-  void DisplayWillDrawAndSwap(bool will_draw_and_swap,
-                              const RenderPassList& render_passes) override;
-  void DisplayDidDrawAndSwap() override;
-
- protected:
-  std::unique_ptr<CompositorFrameSinkSupport> support_;  // protected for test.
-
- private:
-  // CompositorFrameSinkSupportClient implementation:
-  void DidReceiveCompositorFrameAck(
-      const std::vector<ReturnedResource>& resources) override;
-  void OnBeginFrame(const BeginFrameArgs& args) override;
-  void ReclaimResources(
-      const std::vector<ReturnedResource>& resources) override;
-  void WillDrawSurface(const viz::LocalSurfaceId& local_surface_id,
-                       const gfx::Rect& damage_rect) override;
-
-  // ExternalBeginFrameSourceClient implementation:
-  void OnNeedsBeginFrames(bool needs_begin_frame) override;
-
-  // This class is only meant to be used on a single thread.
-  base::ThreadChecker thread_checker_;
-
-  const viz::FrameSinkId frame_sink_id_;
-  viz::LocalSurfaceId local_surface_id_;
-  FrameSinkManager* frame_sink_manager_;
-  viz::LocalSurfaceIdAllocator local_surface_id_allocator_;
-  Display* display_;
-  gfx::Size last_swap_frame_size_;
-  float device_scale_factor_ = 1.f;
-  bool is_lost_ = false;
-  std::unique_ptr<ExternalBeginFrameSource> begin_frame_source_;
-
-  DISALLOW_COPY_AND_ASSIGN(DirectLayerTreeFrameSink);
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_DIRECT_LAYER_TREE_FRAME_SINK_H_
diff --git a/cc/surfaces/direct_layer_tree_frame_sink_unittest.cc b/cc/surfaces/direct_layer_tree_frame_sink_unittest.cc
deleted file mode 100644
index a43443f..0000000
--- a/cc/surfaces/direct_layer_tree_frame_sink_unittest.cc
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/surfaces/direct_layer_tree_frame_sink.h"
-
-#include <memory>
-
-#include "base/memory/ptr_util.h"
-#include "cc/output/renderer_settings.h"
-#include "cc/output/texture_mailbox_deleter.h"
-#include "cc/scheduler/begin_frame_source.h"
-#include "cc/scheduler/delay_based_time_source.h"
-#include "cc/surfaces/display.h"
-#include "cc/surfaces/display_scheduler.h"
-#include "cc/surfaces/frame_sink_manager.h"
-#include "cc/test/begin_frame_args_test.h"
-#include "cc/test/compositor_frame_helpers.h"
-#include "cc/test/fake_layer_tree_frame_sink_client.h"
-#include "cc/test/fake_output_surface.h"
-#include "cc/test/ordered_simple_task_runner.h"
-#include "cc/test/test_context_provider.h"
-#include "cc/test/test_gpu_memory_buffer_manager.h"
-#include "cc/test/test_shared_bitmap_manager.h"
-#include "components/viz/common/frame_sink_id.h"
-#include "components/viz/common/local_surface_id_allocator.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-static constexpr viz::FrameSinkId kArbitraryFrameSinkId(1, 1);
-
-class TestDirectLayerTreeFrameSink : public DirectLayerTreeFrameSink {
- public:
-  using DirectLayerTreeFrameSink::DirectLayerTreeFrameSink;
-
-  CompositorFrameSinkSupport* support() const { return support_.get(); }
-};
-
-class DirectLayerTreeFrameSinkTest : public testing::Test {
- public:
-  DirectLayerTreeFrameSinkTest()
-      : now_src_(new base::SimpleTestTickClock()),
-        task_runner_(new OrderedSimpleTaskRunner(now_src_.get(), true)),
-        display_size_(1920, 1080),
-        display_rect_(display_size_),
-        context_provider_(TestContextProvider::Create()) {
-    frame_sink_manager_.RegisterFrameSinkId(kArbitraryFrameSinkId);
-
-    std::unique_ptr<FakeOutputSurface> display_output_surface =
-        FakeOutputSurface::Create3d();
-    display_output_surface_ = display_output_surface.get();
-
-    begin_frame_source_.reset(new BackToBackBeginFrameSource(
-        base::MakeUnique<DelayBasedTimeSource>(task_runner_.get())));
-
-    int max_frames_pending = 2;
-    std::unique_ptr<DisplayScheduler> scheduler(new DisplayScheduler(
-        begin_frame_source_.get(), task_runner_.get(), max_frames_pending));
-
-    display_.reset(new Display(
-        &bitmap_manager_, &gpu_memory_buffer_manager_, RendererSettings(),
-        kArbitraryFrameSinkId, std::move(display_output_surface),
-        std::move(scheduler),
-        base::MakeUnique<TextureMailboxDeleter>(task_runner_.get())));
-    layer_tree_frame_sink_.reset(new TestDirectLayerTreeFrameSink(
-        kArbitraryFrameSinkId, &frame_sink_manager_, display_.get(),
-        context_provider_, nullptr, &gpu_memory_buffer_manager_,
-        &bitmap_manager_));
-
-    layer_tree_frame_sink_->BindToClient(&layer_tree_frame_sink_client_);
-    display_->Resize(display_size_);
-    display_->SetVisible(true);
-
-    EXPECT_FALSE(
-        layer_tree_frame_sink_client_.did_lose_layer_tree_frame_sink_called());
-  }
-
-  ~DirectLayerTreeFrameSinkTest() override {
-    layer_tree_frame_sink_->DetachFromClient();
-  }
-
-  void SwapBuffersWithDamage(const gfx::Rect& damage_rect) {
-    std::unique_ptr<RenderPass> render_pass(RenderPass::Create());
-    render_pass->SetNew(1, display_rect_, damage_rect, gfx::Transform());
-
-    CompositorFrame frame = test::MakeEmptyCompositorFrame();
-    frame.metadata.begin_frame_ack = BeginFrameAck(0, 1, 1, true);
-    frame.render_pass_list.push_back(std::move(render_pass));
-
-    layer_tree_frame_sink_->SubmitCompositorFrame(std::move(frame));
-  }
-
-  void SetUp() override {
-    // Draw the first frame to start in an "unlocked" state.
-    SwapBuffersWithDamage(display_rect_);
-
-    EXPECT_EQ(0u, display_output_surface_->num_sent_frames());
-    task_runner_->RunUntilIdle();
-    EXPECT_EQ(1u, display_output_surface_->num_sent_frames());
-  }
-
- protected:
-  std::unique_ptr<base::SimpleTestTickClock> now_src_;
-  scoped_refptr<OrderedSimpleTaskRunner> task_runner_;
-
-  const gfx::Size display_size_;
-  const gfx::Rect display_rect_;
-  FrameSinkManager frame_sink_manager_;
-  TestSharedBitmapManager bitmap_manager_;
-  TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
-
-  scoped_refptr<TestContextProvider> context_provider_;
-  FakeOutputSurface* display_output_surface_ = nullptr;
-  std::unique_ptr<BackToBackBeginFrameSource> begin_frame_source_;
-  std::unique_ptr<Display> display_;
-  FakeLayerTreeFrameSinkClient layer_tree_frame_sink_client_;
-  std::unique_ptr<TestDirectLayerTreeFrameSink> layer_tree_frame_sink_;
-};
-
-TEST_F(DirectLayerTreeFrameSinkTest, DamageTriggersSwapBuffers) {
-  SwapBuffersWithDamage(display_rect_);
-  EXPECT_EQ(1u, display_output_surface_->num_sent_frames());
-  task_runner_->RunUntilIdle();
-  EXPECT_EQ(2u, display_output_surface_->num_sent_frames());
-}
-
-TEST_F(DirectLayerTreeFrameSinkTest, NoDamageDoesNotTriggerSwapBuffers) {
-  SwapBuffersWithDamage(gfx::Rect());
-  EXPECT_EQ(1u, display_output_surface_->num_sent_frames());
-  task_runner_->RunUntilIdle();
-  EXPECT_EQ(1u, display_output_surface_->num_sent_frames());
-}
-
-TEST_F(DirectLayerTreeFrameSinkTest, SuspendedDoesNotTriggerSwapBuffers) {
-  SwapBuffersWithDamage(display_rect_);
-  EXPECT_EQ(1u, display_output_surface_->num_sent_frames());
-  display_output_surface_->set_suspended_for_recycle(true);
-  task_runner_->RunUntilIdle();
-  EXPECT_EQ(1u, display_output_surface_->num_sent_frames());
-  SwapBuffersWithDamage(display_rect_);
-  task_runner_->RunUntilIdle();
-  EXPECT_EQ(1u, display_output_surface_->num_sent_frames());
-  display_output_surface_->set_suspended_for_recycle(false);
-  SwapBuffersWithDamage(display_rect_);
-  task_runner_->RunUntilIdle();
-  EXPECT_EQ(2u, display_output_surface_->num_sent_frames());
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/surfaces/display.cc b/cc/surfaces/display.cc
deleted file mode 100644
index bd5782d85..0000000
--- a/cc/surfaces/display.cc
+++ /dev/null
@@ -1,433 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/surfaces/display.h"
-
-#include <stddef.h>
-
-#include "base/memory/ptr_util.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/timer/elapsed_timer.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/benchmarks/benchmark_instrumentation.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/direct_renderer.h"
-#include "cc/output/gl_renderer.h"
-#include "cc/output/renderer_settings.h"
-#include "cc/output/software_renderer.h"
-#include "cc/output/texture_mailbox_deleter.h"
-#include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/display_client.h"
-#include "cc/surfaces/display_scheduler.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_aggregator.h"
-#include "cc/surfaces/surface_manager.h"
-#include "gpu/command_buffer/client/gles2_interface.h"
-#include "gpu/vulkan/features.h"
-#include "ui/gfx/buffer_types.h"
-
-#if BUILDFLAG(ENABLE_VULKAN)
-#include "cc/output/vulkan_renderer.h"
-#endif
-
-namespace cc {
-
-Display::Display(viz::SharedBitmapManager* bitmap_manager,
-                 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-                 const RendererSettings& settings,
-                 const viz::FrameSinkId& frame_sink_id,
-                 std::unique_ptr<OutputSurface> output_surface,
-                 std::unique_ptr<DisplayScheduler> scheduler,
-                 std::unique_ptr<TextureMailboxDeleter> texture_mailbox_deleter)
-    : bitmap_manager_(bitmap_manager),
-      gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
-      settings_(settings),
-      frame_sink_id_(frame_sink_id),
-      output_surface_(std::move(output_surface)),
-      scheduler_(std::move(scheduler)),
-      texture_mailbox_deleter_(std::move(texture_mailbox_deleter)) {
-  DCHECK(output_surface_);
-  DCHECK(frame_sink_id_.is_valid());
-  if (scheduler_)
-    scheduler_->SetClient(this);
-}
-
-Display::~Display() {
-  // Only do this if Initialize() happened.
-  if (client_) {
-    if (auto* context = output_surface_->context_provider())
-      context->SetLostContextCallback(base::Closure());
-    if (scheduler_)
-      surface_manager_->RemoveObserver(scheduler_.get());
-  }
-  if (aggregator_) {
-    for (const auto& id_entry : aggregator_->previous_contained_surfaces()) {
-      Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first);
-      if (surface)
-        surface->RunDrawCallback();
-    }
-  }
-}
-
-void Display::Initialize(DisplayClient* client,
-                         SurfaceManager* surface_manager) {
-  DCHECK(client);
-  DCHECK(surface_manager);
-  client_ = client;
-  surface_manager_ = surface_manager;
-  if (scheduler_)
-    surface_manager_->AddObserver(scheduler_.get());
-
-  output_surface_->BindToClient(this);
-  InitializeRenderer();
-
-  if (auto* context = output_surface_->context_provider()) {
-    // This depends on assumptions that Display::Initialize will happen
-    // on the same callstack as the ContextProvider being created/initialized
-    // or else it could miss a callback before setting this.
-    context->SetLostContextCallback(base::Bind(
-        &Display::DidLoseContextProvider,
-        // Unretained is safe since the callback is unset in this class'
-        // destructor and is never posted.
-        base::Unretained(this)));
-  }
-}
-
-void Display::SetLocalSurfaceId(const viz::LocalSurfaceId& id,
-                                float device_scale_factor) {
-  if (current_surface_id_.local_surface_id() == id &&
-      device_scale_factor_ == device_scale_factor) {
-    return;
-  }
-
-  TRACE_EVENT0("cc", "Display::SetSurfaceId");
-  current_surface_id_ = viz::SurfaceId(frame_sink_id_, id);
-  device_scale_factor_ = device_scale_factor;
-
-  UpdateRootSurfaceResourcesLocked();
-  if (scheduler_)
-    scheduler_->SetNewRootSurface(current_surface_id_);
-}
-
-void Display::SetVisible(bool visible) {
-  TRACE_EVENT1("cc", "Display::SetVisible", "visible", visible);
-  if (renderer_)
-    renderer_->SetVisible(visible);
-  if (scheduler_)
-    scheduler_->SetVisible(visible);
-  visible_ = visible;
-
-  if (!visible) {
-    // Damage tracker needs a full reset as renderer resources are dropped when
-    // not visible.
-    if (aggregator_ && current_surface_id_.is_valid())
-      aggregator_->SetFullDamageForSurface(current_surface_id_);
-  }
-}
-
-void Display::Resize(const gfx::Size& size) {
-  if (size == current_surface_size_)
-    return;
-
-  TRACE_EVENT0("cc", "Display::Resize");
-
-  // Need to ensure all pending swaps have executed before the window is
-  // resized, or D3D11 will scale the swap output.
-  if (settings_.finish_rendering_on_resize) {
-    if (!swapped_since_resize_ && scheduler_)
-      scheduler_->ForceImmediateSwapIfPossible();
-    if (swapped_since_resize_ && output_surface_ &&
-        output_surface_->context_provider())
-      output_surface_->context_provider()->ContextGL()->ShallowFinishCHROMIUM();
-  }
-  swapped_since_resize_ = false;
-  current_surface_size_ = size;
-  if (scheduler_)
-    scheduler_->DisplayResized();
-}
-
-void Display::SetColorSpace(const gfx::ColorSpace& blending_color_space,
-                            const gfx::ColorSpace& device_color_space) {
-  blending_color_space_ = blending_color_space;
-  device_color_space_ = device_color_space;
-  if (aggregator_) {
-    aggregator_->SetOutputColorSpace(blending_color_space, device_color_space_);
-  }
-}
-
-void Display::SetOutputIsSecure(bool secure) {
-  if (secure == output_is_secure_)
-    return;
-  output_is_secure_ = secure;
-
-  if (aggregator_) {
-    aggregator_->set_output_is_secure(secure);
-    // Force a redraw.
-    if (current_surface_id_.is_valid())
-      aggregator_->SetFullDamageForSurface(current_surface_id_);
-  }
-}
-
-void Display::InitializeRenderer() {
-  // Not relevant for display compositor since it's not delegated.
-  constexpr bool delegated_sync_points_required = false;
-  resource_provider_.reset(new ResourceProvider(
-      output_surface_->context_provider(), bitmap_manager_,
-      gpu_memory_buffer_manager_, nullptr, delegated_sync_points_required,
-      settings_.enable_color_correct_rendering, settings_.resource_settings));
-
-  if (output_surface_->context_provider()) {
-    DCHECK(texture_mailbox_deleter_);
-    renderer_ = base::MakeUnique<GLRenderer>(&settings_, output_surface_.get(),
-                                             resource_provider_.get(),
-                                             texture_mailbox_deleter_.get());
-  } else if (output_surface_->vulkan_context_provider()) {
-#if defined(ENABLE_VULKAN)
-    DCHECK(texture_mailbox_deleter_);
-    renderer_ = base::MakeUnique<VulkanRenderer>(
-        &settings_, output_surface_.get(), resource_provider_.get(),
-        texture_mailbox_deleter_.get(), settings_.highp_threshold_min);
-#else
-    NOTREACHED();
-#endif
-  } else {
-    auto renderer = base::MakeUnique<SoftwareRenderer>(
-        &settings_, output_surface_.get(), resource_provider_.get());
-    software_renderer_ = renderer.get();
-    renderer_ = std::move(renderer);
-  }
-
-  renderer_->Initialize();
-  renderer_->SetVisible(visible_);
-
-  // TODO(jbauman): Outputting an incomplete quad list doesn't work when using
-  // overlays.
-  bool output_partial_list = renderer_->use_partial_swap() &&
-                             !output_surface_->GetOverlayCandidateValidator();
-  aggregator_.reset(new SurfaceAggregator(
-      surface_manager_, resource_provider_.get(), output_partial_list));
-  aggregator_->set_output_is_secure(output_is_secure_);
-  aggregator_->SetOutputColorSpace(blending_color_space_, device_color_space_);
-}
-
-void Display::UpdateRootSurfaceResourcesLocked() {
-  Surface* surface = surface_manager_->GetSurfaceForId(current_surface_id_);
-  bool root_surface_resources_locked = !surface || !surface->HasActiveFrame();
-  if (scheduler_)
-    scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked);
-}
-
-void Display::DidLoseContextProvider() {
-  if (scheduler_)
-    scheduler_->OutputSurfaceLost();
-  // WARNING: The client may delete the Display in this method call. Do not
-  // make any additional references to members after this call.
-  client_->DisplayOutputSurfaceLost();
-}
-
-bool Display::DrawAndSwap() {
-  TRACE_EVENT0("cc", "Display::DrawAndSwap");
-
-  if (!current_surface_id_.is_valid()) {
-    TRACE_EVENT_INSTANT0("cc", "No root surface.", TRACE_EVENT_SCOPE_THREAD);
-    return false;
-  }
-
-  if (!output_surface_) {
-    TRACE_EVENT_INSTANT0("cc", "No output surface", TRACE_EVENT_SCOPE_THREAD);
-    return false;
-  }
-
-  base::ElapsedTimer aggregate_timer;
-  CompositorFrame frame = aggregator_->Aggregate(current_surface_id_);
-  UMA_HISTOGRAM_COUNTS_1M("Compositing.SurfaceAggregator.AggregateUs",
-                          aggregate_timer.Elapsed().InMicroseconds());
-
-  if (frame.render_pass_list.empty()) {
-    TRACE_EVENT_INSTANT0("cc", "Empty aggregated frame.",
-                         TRACE_EVENT_SCOPE_THREAD);
-    return false;
-  }
-
-  // Run callbacks early to allow pipelining.
-  for (const auto& id_entry : aggregator_->previous_contained_surfaces()) {
-    Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first);
-    if (surface)
-      surface->RunDrawCallback();
-  }
-
-  frame.metadata.latency_info.insert(frame.metadata.latency_info.end(),
-                                     stored_latency_info_.begin(),
-                                     stored_latency_info_.end());
-  stored_latency_info_.clear();
-  bool have_copy_requests = false;
-  for (const auto& pass : frame.render_pass_list) {
-    have_copy_requests |= !pass->copy_requests.empty();
-  }
-
-  gfx::Size surface_size;
-  bool have_damage = false;
-  RenderPass& last_render_pass = *frame.render_pass_list.back();
-  if (last_render_pass.output_rect.size() != current_surface_size_ &&
-      last_render_pass.damage_rect == last_render_pass.output_rect &&
-      !current_surface_size_.IsEmpty()) {
-    // Resize the output rect to the current surface size so that we won't
-    // skip the draw and so that the GL swap won't stretch the output.
-    last_render_pass.output_rect.set_size(current_surface_size_);
-    last_render_pass.damage_rect = last_render_pass.output_rect;
-  }
-  surface_size = last_render_pass.output_rect.size();
-  have_damage = !last_render_pass.damage_rect.size().IsEmpty();
-
-  bool size_matches = surface_size == current_surface_size_;
-  if (!size_matches)
-    TRACE_EVENT_INSTANT0("cc", "Size mismatch.", TRACE_EVENT_SCOPE_THREAD);
-
-  bool should_draw = have_copy_requests || (have_damage && size_matches);
-
-  // If the surface is suspended then the resources to be used by the draw are
-  // likely destroyed.
-  if (output_surface_->SurfaceIsSuspendForRecycle()) {
-    TRACE_EVENT_INSTANT0("cc", "Surface is suspended for recycle.",
-                         TRACE_EVENT_SCOPE_THREAD);
-    should_draw = false;
-  }
-
-  client_->DisplayWillDrawAndSwap(should_draw, frame.render_pass_list);
-
-  if (should_draw) {
-    bool disable_image_filtering =
-        frame.metadata.is_resourceless_software_draw_with_scroll_or_animation;
-    if (software_renderer_) {
-      software_renderer_->SetDisablePictureQuadImageFiltering(
-          disable_image_filtering);
-    } else {
-      // This should only be set for software draws in synchronous compositor.
-      DCHECK(!disable_image_filtering);
-    }
-
-    base::ElapsedTimer draw_timer;
-    renderer_->DecideRenderPassAllocationsForFrame(frame.render_pass_list);
-    renderer_->DrawFrame(&frame.render_pass_list, device_scale_factor_,
-                         current_surface_size_);
-    if (software_renderer_) {
-      UMA_HISTOGRAM_COUNTS_1M("Compositing.DirectRenderer.Software.DrawFrameUs",
-                              draw_timer.Elapsed().InMicroseconds());
-    } else {
-      UMA_HISTOGRAM_COUNTS_1M("Compositing.DirectRenderer.GL.DrawFrameUs",
-                              draw_timer.Elapsed().InMicroseconds());
-    }
-  } else {
-    TRACE_EVENT_INSTANT0("cc", "Draw skipped.", TRACE_EVENT_SCOPE_THREAD);
-  }
-
-  bool should_swap = should_draw && size_matches;
-  if (should_swap) {
-    swapped_since_resize_ = true;
-    for (auto& latency : frame.metadata.latency_info) {
-      TRACE_EVENT_WITH_FLOW1(
-          "input,benchmark", "LatencyInfo.Flow",
-          TRACE_ID_DONT_MANGLE(latency.trace_id()),
-          TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step",
-          "Display::DrawAndSwap");
-    }
-    benchmark_instrumentation::IssueDisplayRenderingStatsEvent();
-    renderer_->SwapBuffers(std::move(frame.metadata.latency_info));
-    if (scheduler_)
-      scheduler_->DidSwapBuffers();
-  } else {
-    if (have_damage && !size_matches)
-      aggregator_->SetFullDamageForSurface(current_surface_id_);
-    TRACE_EVENT_INSTANT0("cc", "Swap skipped.", TRACE_EVENT_SCOPE_THREAD);
-
-    // Do not store more that the allowed size.
-    if (ui::LatencyInfo::Verify(frame.metadata.latency_info,
-                                "Display::DrawAndSwap")) {
-      stored_latency_info_.insert(stored_latency_info_.end(),
-                                  frame.metadata.latency_info.begin(),
-                                  frame.metadata.latency_info.end());
-    }
-
-    if (scheduler_) {
-      scheduler_->DidSwapBuffers();
-      scheduler_->DidReceiveSwapBuffersAck();
-    }
-  }
-
-  client_->DisplayDidDrawAndSwap();
-  return true;
-}
-
-void Display::DidReceiveSwapBuffersAck() {
-  if (scheduler_)
-    scheduler_->DidReceiveSwapBuffersAck();
-  if (renderer_)
-    renderer_->SwapBuffersComplete();
-}
-
-void Display::DidReceiveTextureInUseResponses(
-    const gpu::TextureInUseResponses& responses) {
-  if (renderer_)
-    renderer_->DidReceiveTextureInUseResponses(responses);
-}
-
-void Display::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
-  aggregator_->SetFullDamageForSurface(current_surface_id_);
-  if (scheduler_) {
-    BeginFrameAck ack;
-    ack.has_damage = true;
-    scheduler_->ProcessSurfaceDamage(current_surface_id_, ack, true);
-  }
-}
-
-bool Display::SurfaceDamaged(const viz::SurfaceId& surface_id,
-                             const BeginFrameAck& ack) {
-  bool display_damaged = false;
-  if (ack.has_damage) {
-    if (aggregator_ &&
-        aggregator_->previous_contained_surfaces().count(surface_id)) {
-      Surface* surface = surface_manager_->GetSurfaceForId(surface_id);
-      if (surface) {
-        DCHECK(surface->HasActiveFrame());
-        if (surface->GetActiveFrame().resource_list.empty())
-          aggregator_->ReleaseResources(surface_id);
-      }
-      display_damaged = true;
-      if (surface_id == current_surface_id_)
-        UpdateRootSurfaceResourcesLocked();
-    } else if (surface_id == current_surface_id_) {
-      display_damaged = true;
-      UpdateRootSurfaceResourcesLocked();
-    }
-  }
-
-  return display_damaged;
-}
-
-void Display::SurfaceDiscarded(const viz::SurfaceId& surface_id) {
-  if (aggregator_)
-    aggregator_->ReleaseResources(surface_id);
-}
-
-bool Display::SurfaceHasUndrawnFrame(const viz::SurfaceId& surface_id) const {
-  if (!surface_manager_)
-    return false;
-
-  Surface* surface = surface_manager_->GetSurfaceForId(surface_id);
-  if (!surface)
-    return false;
-
-  return surface->HasUndrawnActiveFrame();
-}
-
-const viz::SurfaceId& Display::CurrentSurfaceId() {
-  return current_surface_id_;
-}
-
-void Display::ForceImmediateDrawAndSwapIfPossible() {
-  if (scheduler_)
-    scheduler_->ForceImmediateSwapIfPossible();
-}
-
-}  // namespace cc
diff --git a/cc/surfaces/display.h b/cc/surfaces/display.h
deleted file mode 100644
index b40050c..0000000
--- a/cc/surfaces/display.h
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_SURFACES_DISPLAY_H_
-#define CC_SURFACES_DISPLAY_H_
-
-#include <memory>
-#include <vector>
-
-#include "base/macros.h"
-#include "cc/output/output_surface_client.h"
-#include "cc/resources/returned_resource.h"
-#include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/display_scheduler.h"
-#include "cc/surfaces/surface_aggregator.h"
-#include "cc/surfaces/surface_manager.h"
-#include "cc/surfaces/surfaces_export.h"
-#include "components/viz/common/frame_sink_id.h"
-#include "components/viz/common/surface_id.h"
-#include "gpu/command_buffer/common/texture_in_use_response.h"
-#include "ui/gfx/color_space.h"
-#include "ui/latency/latency_info.h"
-
-namespace gpu {
-class GpuMemoryBufferManager;
-}
-
-namespace gfx {
-class Size;
-}
-
-namespace viz {
-class SharedBitmapManager;
-}
-
-namespace cc {
-
-class DirectRenderer;
-class DisplayClient;
-class OutputSurface;
-class RendererSettings;
-class ResourceProvider;
-class SoftwareRenderer;
-class TextureMailboxDeleter;
-
-// A Display produces a surface that can be used to draw to a physical display
-// (OutputSurface). The client is responsible for creating and sizing the
-// surface IDs used to draw into the display and deciding when to draw.
-class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient,
-                                   public OutputSurfaceClient {
- public:
-  // The |begin_frame_source| and |scheduler| may be null (together). In that
-  // case, DrawAndSwap must be called externally when needed.
-  Display(viz::SharedBitmapManager* bitmap_manager,
-          gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-          const RendererSettings& settings,
-          const viz::FrameSinkId& frame_sink_id,
-          std::unique_ptr<OutputSurface> output_surface,
-          std::unique_ptr<DisplayScheduler> scheduler,
-          std::unique_ptr<TextureMailboxDeleter> texture_mailbox_deleter);
-
-  ~Display() override;
-
-  void Initialize(DisplayClient* client, SurfaceManager* surface_manager);
-
-  // device_scale_factor is used to communicate to the external window system
-  // what scale this was rendered at.
-  void SetLocalSurfaceId(const viz::LocalSurfaceId& id,
-                         float device_scale_factor);
-  void SetVisible(bool visible);
-  void Resize(const gfx::Size& new_size);
-  void SetColorSpace(const gfx::ColorSpace& blending_color_space,
-                     const gfx::ColorSpace& device_color_space);
-  void SetOutputIsSecure(bool secure);
-
-  const viz::SurfaceId& CurrentSurfaceId();
-
-  // DisplaySchedulerClient implementation.
-  bool DrawAndSwap() override;
-  bool SurfaceHasUndrawnFrame(const viz::SurfaceId& surface_id) const override;
-  bool SurfaceDamaged(const viz::SurfaceId& surface_id,
-                      const BeginFrameAck& ack) override;
-  void SurfaceDiscarded(const viz::SurfaceId& surface_id) override;
-
-  // OutputSurfaceClient implementation.
-  void SetNeedsRedrawRect(const gfx::Rect& damage_rect) override;
-  void DidReceiveSwapBuffersAck() override;
-  void DidReceiveTextureInUseResponses(
-      const gpu::TextureInUseResponses& responses) override;
-
-  bool has_scheduler() const { return !!scheduler_; }
-  DirectRenderer* renderer_for_testing() const { return renderer_.get(); }
-  size_t stored_latency_info_size_for_testing() const {
-    return stored_latency_info_.size();
-  }
-
-  void ForceImmediateDrawAndSwapIfPossible();
-
- private:
-  void InitializeRenderer();
-  void UpdateRootSurfaceResourcesLocked();
-  void DidLoseContextProvider();
-
-  viz::SharedBitmapManager* const bitmap_manager_;
-  gpu::GpuMemoryBufferManager* const gpu_memory_buffer_manager_;
-  const RendererSettings settings_;
-
-  DisplayClient* client_ = nullptr;
-  SurfaceManager* surface_manager_ = nullptr;
-  const viz::FrameSinkId frame_sink_id_;
-  viz::SurfaceId current_surface_id_;
-  gfx::Size current_surface_size_;
-  float device_scale_factor_ = 1.f;
-  gfx::ColorSpace blending_color_space_ = gfx::ColorSpace::CreateSRGB();
-  gfx::ColorSpace device_color_space_ = gfx::ColorSpace::CreateSRGB();
-  bool visible_ = false;
-  bool swapped_since_resize_ = false;
-  bool output_is_secure_ = false;
-
-  std::unique_ptr<OutputSurface> output_surface_;
-  std::unique_ptr<DisplayScheduler> scheduler_;
-  std::unique_ptr<ResourceProvider> resource_provider_;
-  std::unique_ptr<SurfaceAggregator> aggregator_;
-  std::unique_ptr<TextureMailboxDeleter> texture_mailbox_deleter_;
-  std::unique_ptr<DirectRenderer> renderer_;
-  SoftwareRenderer* software_renderer_ = nullptr;
-  std::vector<ui::LatencyInfo> stored_latency_info_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(Display);
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_DISPLAY_H_
diff --git a/cc/surfaces/display_client.h b/cc/surfaces/display_client.h
deleted file mode 100644
index 85dff17..0000000
--- a/cc/surfaces/display_client.h
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_SURFACES_DISPLAY_CLIENT_H_
-#define CC_SURFACES_DISPLAY_CLIENT_H_
-
-#include "cc/quads/render_pass.h"
-
-namespace cc {
-
-class DisplayClient {
- public:
-  virtual ~DisplayClient() {}
-  virtual void DisplayOutputSurfaceLost() = 0;
-  virtual void DisplayWillDrawAndSwap(bool will_draw_and_swap,
-                                      const RenderPassList& render_passes) = 0;
-  virtual void DisplayDidDrawAndSwap() = 0;
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_DISPLAY_CLIENT_H_
diff --git a/cc/surfaces/display_scheduler.cc b/cc/surfaces/display_scheduler.cc
deleted file mode 100644
index c1450ce..0000000
--- a/cc/surfaces/display_scheduler.cc
+++ /dev/null
@@ -1,491 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/surfaces/display_scheduler.h"
-
-#include <vector>
-
-#include "base/auto_reset.h"
-#include "base/stl_util.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/output/output_surface.h"
-#include "cc/surfaces/surface_info.h"
-
-namespace cc {
-
-DisplayScheduler::DisplayScheduler(BeginFrameSource* begin_frame_source,
-                                   base::SingleThreadTaskRunner* task_runner,
-                                   int max_pending_swaps,
-                                   bool wait_for_all_surfaces_before_draw)
-    : client_(nullptr),
-      begin_frame_source_(begin_frame_source),
-      task_runner_(task_runner),
-      inside_surface_damaged_(false),
-      visible_(false),
-      output_surface_lost_(false),
-      root_surface_resources_locked_(true),
-      inside_begin_frame_deadline_interval_(false),
-      needs_draw_(false),
-      expecting_root_surface_damage_because_of_resize_(false),
-      has_pending_surfaces_(false),
-      next_swap_id_(1),
-      pending_swaps_(0),
-      max_pending_swaps_(max_pending_swaps),
-      wait_for_all_surfaces_before_draw_(wait_for_all_surfaces_before_draw),
-      observing_begin_frame_source_(false),
-      weak_ptr_factory_(this) {
-  begin_frame_deadline_closure_ = base::Bind(
-      &DisplayScheduler::OnBeginFrameDeadline, weak_ptr_factory_.GetWeakPtr());
-}
-
-DisplayScheduler::~DisplayScheduler() {
-  StopObservingBeginFrames();
-}
-
-void DisplayScheduler::SetClient(DisplaySchedulerClient* client) {
-  client_ = client;
-}
-
-void DisplayScheduler::SetVisible(bool visible) {
-  if (visible_ == visible)
-    return;
-
-  visible_ = visible;
-  // If going invisible, we'll stop observing begin frames once we try
-  // to draw and fail.
-  StartObservingBeginFrames();
-  ScheduleBeginFrameDeadline();
-}
-
-// If we try to draw when the root surface resources are locked, the
-// draw will fail.
-void DisplayScheduler::SetRootSurfaceResourcesLocked(bool locked) {
-  TRACE_EVENT1("cc", "DisplayScheduler::SetRootSurfaceResourcesLocked",
-               "locked", locked);
-  root_surface_resources_locked_ = locked;
-  ScheduleBeginFrameDeadline();
-}
-
-// This is used to force an immediate swap before a resize.
-void DisplayScheduler::ForceImmediateSwapIfPossible() {
-  TRACE_EVENT0("cc", "DisplayScheduler::ForceImmediateSwapIfPossible");
-  bool in_begin = inside_begin_frame_deadline_interval_;
-  bool did_draw = AttemptDrawAndSwap();
-  if (in_begin)
-    DidFinishFrame(did_draw);
-}
-
-void DisplayScheduler::DisplayResized() {
-  expecting_root_surface_damage_because_of_resize_ = true;
-  needs_draw_ = true;
-  ScheduleBeginFrameDeadline();
-}
-
-// Notification that there was a resize or the root surface changed and
-// that we should just draw immediately.
-void DisplayScheduler::SetNewRootSurface(
-    const viz::SurfaceId& root_surface_id) {
-  TRACE_EVENT0("cc", "DisplayScheduler::SetNewRootSurface");
-  root_surface_id_ = root_surface_id;
-  BeginFrameAck ack;
-  ack.has_damage = true;
-  ProcessSurfaceDamage(root_surface_id, ack, true);
-}
-
-// Indicates that there was damage to one of the surfaces.
-// Has some logic to wait for multiple active surfaces before
-// triggering the deadline.
-void DisplayScheduler::ProcessSurfaceDamage(const viz::SurfaceId& surface_id,
-                                            const BeginFrameAck& ack,
-                                            bool display_damaged) {
-  TRACE_EVENT1("cc", "DisplayScheduler::SurfaceDamaged", "surface_id",
-               surface_id.ToString());
-
-  // We may cause a new BeginFrame to be run inside this method, but to help
-  // avoid being reentrant to the caller of SurfaceDamaged, track when this is
-  // happening with |inside_surface_damaged_|.
-  base::AutoReset<bool> auto_reset(&inside_surface_damaged_, true);
-
-  if (display_damaged) {
-    needs_draw_ = true;
-
-    if (surface_id == root_surface_id_)
-      expecting_root_surface_damage_because_of_resize_ = false;
-
-    StartObservingBeginFrames();
-  }
-
-  // Update surface state.
-  bool valid_ack = ack.sequence_number != BeginFrameArgs::kInvalidFrameNumber;
-  if (valid_ack) {
-    auto it = surface_states_.find(surface_id);
-    if (it != surface_states_.end())
-      it->second.last_ack = ack;
-    else
-      valid_ack = false;
-  }
-
-  bool pending_surfaces_changed = false;
-  if (display_damaged || valid_ack)
-    pending_surfaces_changed = UpdateHasPendingSurfaces();
-
-  if (display_damaged || pending_surfaces_changed)
-    ScheduleBeginFrameDeadline();
-}
-
-bool DisplayScheduler::UpdateHasPendingSurfaces() {
-  // If we're not currently inside a deadline interval, we will call
-  // UpdateHasPendingSurfaces() again during OnBeginFrameImpl().
-  if (!inside_begin_frame_deadline_interval_ || !client_)
-    return false;
-
-  bool old_value = has_pending_surfaces_;
-
-  for (const std::pair<viz::SurfaceId, SurfaceBeginFrameState>& entry :
-       surface_states_) {
-    const viz::SurfaceId& surface_id = entry.first;
-    const SurfaceBeginFrameState& state = entry.second;
-
-    // Surface is ready if it hasn't received the current BeginFrame or receives
-    // BeginFrames from a different source and thus likely belongs to a
-    // different surface hierarchy.
-    uint32_t source_id = current_begin_frame_args_.source_id;
-    uint64_t sequence_number = current_begin_frame_args_.sequence_number;
-    if (!state.last_args.IsValid() || state.last_args.source_id != source_id ||
-        state.last_args.sequence_number != sequence_number) {
-      continue;
-    }
-
-    // Surface is ready if it has acknowledged the current BeginFrame.
-    if (state.last_ack.source_id == source_id &&
-        state.last_ack.sequence_number == sequence_number) {
-      continue;
-    }
-
-    // Surface is ready if there is an undrawn active CompositorFrame, because
-    // its producer is CompositorFrameAck throttled.
-    if (client_->SurfaceHasUndrawnFrame(entry.first))
-      continue;
-
-    has_pending_surfaces_ = true;
-    TRACE_EVENT_INSTANT2("cc", "DisplayScheduler::UpdateHasPendingSurfaces",
-                         TRACE_EVENT_SCOPE_THREAD, "has_pending_surfaces",
-                         has_pending_surfaces_, "pending_surface_id",
-                         surface_id.ToString());
-    return has_pending_surfaces_ != old_value;
-  }
-  has_pending_surfaces_ = false;
-  TRACE_EVENT_INSTANT1("cc", "DisplayScheduler::UpdateHasPendingSurfaces",
-                       TRACE_EVENT_SCOPE_THREAD, "has_pending_surfaces",
-                       has_pending_surfaces_);
-  return has_pending_surfaces_ != old_value;
-}
-
-void DisplayScheduler::OutputSurfaceLost() {
-  TRACE_EVENT0("cc", "DisplayScheduler::OutputSurfaceLost");
-  output_surface_lost_ = true;
-  ScheduleBeginFrameDeadline();
-}
-
-bool DisplayScheduler::DrawAndSwap() {
-  TRACE_EVENT0("cc", "DisplayScheduler::DrawAndSwap");
-  DCHECK_LT(pending_swaps_, max_pending_swaps_);
-  DCHECK(!output_surface_lost_);
-
-  bool success = client_->DrawAndSwap();
-  if (!success)
-    return false;
-
-  needs_draw_ = false;
-  return true;
-}
-
-bool DisplayScheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) {
-  base::TimeTicks now = base::TimeTicks::Now();
-  TRACE_EVENT2("cc", "DisplayScheduler::BeginFrame", "args", args.AsValue(),
-               "now", now);
-
-  if (inside_surface_damaged_) {
-    // Repost this so that we don't run a missed BeginFrame on the same
-    // callstack. Otherwise we end up running unexpected scheduler actions
-    // immediately while inside some other action (such as submitting a
-    // CompositorFrame for a SurfaceFactory).
-    DCHECK_EQ(args.type, BeginFrameArgs::MISSED);
-    DCHECK(missed_begin_frame_task_.IsCancelled());
-    missed_begin_frame_task_.Reset(base::Bind(
-        base::IgnoreResult(&DisplayScheduler::OnBeginFrameDerivedImpl),
-        // The CancelableCallback will not run after it is destroyed, which
-        // happens when |this| is destroyed.
-        base::Unretained(this), args));
-    task_runner_->PostTask(FROM_HERE, missed_begin_frame_task_.callback());
-    return true;
-  }
-
-  // Save the |BeginFrameArgs| as the callback (missed_begin_frame_task_) can be
-  // destroyed if we StopObservingBeginFrames(), and it would take the |args|
-  // with it. Instead save the args and cancel the |missed_begin_frame_task_|.
-  BeginFrameArgs save_args = args;
-  // If we get another BeginFrame before a posted missed frame, just drop the
-  // missed frame. Also if this was the missed frame, drop the Callback inside
-  // it.
-  missed_begin_frame_task_.Cancel();
-
-  // If we get another BeginFrame before the previous deadline,
-  // synchronously trigger the previous deadline before progressing.
-  if (inside_begin_frame_deadline_interval_)
-    OnBeginFrameDeadline();
-
-  // Schedule the deadline.
-  current_begin_frame_args_ = save_args;
-  current_begin_frame_args_.deadline -=
-      BeginFrameArgs::DefaultEstimatedParentDrawTime();
-  inside_begin_frame_deadline_interval_ = true;
-  UpdateHasPendingSurfaces();
-  ScheduleBeginFrameDeadline();
-
-  return true;
-}
-
-void DisplayScheduler::StartObservingBeginFrames() {
-  if (!observing_begin_frame_source_ && ShouldDraw()) {
-    begin_frame_source_->AddObserver(this);
-    observing_begin_frame_source_ = true;
-  }
-}
-
-void DisplayScheduler::StopObservingBeginFrames() {
-  if (observing_begin_frame_source_) {
-    begin_frame_source_->RemoveObserver(this);
-    observing_begin_frame_source_ = false;
-
-    // A missed BeginFrame may be queued, so drop that too if we're going to
-    // stop listening.
-    missed_begin_frame_task_.Cancel();
-  }
-}
-
-bool DisplayScheduler::ShouldDraw() {
-  // Note: When any of these cases becomes true, StartObservingBeginFrames must
-  // be called to ensure the draw will happen.
-  return needs_draw_ && !output_surface_lost_ && visible_;
-}
-
-void DisplayScheduler::OnBeginFrameSourcePausedChanged(bool paused) {
-  // BeginFrameSources used with DisplayScheduler do not make use of this
-  // feature.
-  if (paused)
-    NOTIMPLEMENTED();
-}
-
-void DisplayScheduler::OnSurfaceCreated(const SurfaceInfo& surface_info) {}
-
-void DisplayScheduler::OnSurfaceDestroyed(const viz::SurfaceId& surface_id) {
-  auto it = surface_states_.find(surface_id);
-  if (it == surface_states_.end())
-    return;
-  surface_states_.erase(it);
-  if (UpdateHasPendingSurfaces())
-    ScheduleBeginFrameDeadline();
-}
-
-bool DisplayScheduler::OnSurfaceDamaged(const viz::SurfaceId& surface_id,
-                                        const BeginFrameAck& ack) {
-  bool damaged = client_->SurfaceDamaged(surface_id, ack);
-  ProcessSurfaceDamage(surface_id, ack, damaged);
-
-  return damaged;
-}
-
-void DisplayScheduler::OnSurfaceDiscarded(const viz::SurfaceId& surface_id) {
-  client_->SurfaceDiscarded(surface_id);
-}
-
-void DisplayScheduler::OnSurfaceDamageExpected(const viz::SurfaceId& surface_id,
-                                               const BeginFrameArgs& args) {
-  TRACE_EVENT1("cc", "DisplayScheduler::SurfaceDamageExpected", "surface_id",
-               surface_id.ToString());
-  // Insert a new state for the surface if we don't know of it yet. We don't use
-  // OnSurfaceCreated for this, because it may not be called if a
-  // CompositorFrameSinkSupport starts submitting frames to a different Display,
-  // but continues using the same Surface, or if a Surface does not activate its
-  // first CompositorFrame immediately.
-  surface_states_[surface_id].last_args = args;
-  if (UpdateHasPendingSurfaces())
-    ScheduleBeginFrameDeadline();
-}
-
-void DisplayScheduler::OnSurfaceWillDraw(const viz::SurfaceId& surface_id) {}
-
-base::TimeTicks DisplayScheduler::DesiredBeginFrameDeadlineTime() const {
-  switch (AdjustedBeginFrameDeadlineMode()) {
-    case BeginFrameDeadlineMode::kImmediate:
-      return base::TimeTicks();
-    case BeginFrameDeadlineMode::kRegular:
-      return current_begin_frame_args_.deadline;
-    case BeginFrameDeadlineMode::kLate:
-      return current_begin_frame_args_.frame_time +
-             current_begin_frame_args_.interval;
-    case BeginFrameDeadlineMode::kNone:
-      return base::TimeTicks::Max();
-    default:
-      NOTREACHED();
-      return base::TimeTicks();
-  }
-}
-
-DisplayScheduler::BeginFrameDeadlineMode
-DisplayScheduler::AdjustedBeginFrameDeadlineMode() const {
-  BeginFrameDeadlineMode mode = DesiredBeginFrameDeadlineMode();
-
-  // In blocking mode, late and regular deadline should not apply. Wait
-  // indefinitely instead.
-  if (wait_for_all_surfaces_before_draw_ &&
-      (mode == BeginFrameDeadlineMode::kRegular ||
-       mode == BeginFrameDeadlineMode::kLate)) {
-    return BeginFrameDeadlineMode::kNone;
-  }
-
-  return mode;
-}
-
-DisplayScheduler::BeginFrameDeadlineMode
-DisplayScheduler::DesiredBeginFrameDeadlineMode() const {
-  if (output_surface_lost_) {
-    TRACE_EVENT_INSTANT0("cc", "Lost output surface", TRACE_EVENT_SCOPE_THREAD);
-    return BeginFrameDeadlineMode::kImmediate;
-  }
-
-  if (pending_swaps_ >= max_pending_swaps_) {
-    TRACE_EVENT_INSTANT0("cc", "Swap throttled", TRACE_EVENT_SCOPE_THREAD);
-    return BeginFrameDeadlineMode::kLate;
-  }
-
-  if (root_surface_resources_locked_) {
-    TRACE_EVENT_INSTANT0("cc", "Root surface resources locked",
-                         TRACE_EVENT_SCOPE_THREAD);
-    return BeginFrameDeadlineMode::kLate;
-  }
-
-  bool all_surfaces_ready = !has_pending_surfaces_ &&
-                            root_surface_id_.is_valid() &&
-                            !expecting_root_surface_damage_because_of_resize_;
-
-  // When no draw is needed, only allow an early deadline in full-pipe mode.
-  // This way, we can unblock the BeginFrame in full-pipe mode if no draw is
-  // necessary, but accommodate damage as a result of missed BeginFrames from
-  // clients otherwise.
-  bool allow_early_deadline_without_draw = wait_for_all_surfaces_before_draw_;
-
-  if (all_surfaces_ready &&
-      (needs_draw_ || allow_early_deadline_without_draw)) {
-    TRACE_EVENT_INSTANT0("cc", "All active surfaces ready",
-                         TRACE_EVENT_SCOPE_THREAD);
-    return BeginFrameDeadlineMode::kImmediate;
-  }
-
-  if (!needs_draw_) {
-    TRACE_EVENT_INSTANT0("cc", "No damage yet", TRACE_EVENT_SCOPE_THREAD);
-    return BeginFrameDeadlineMode::kLate;
-  }
-
-  // TODO(mithro): Be smarter about resize deadlines.
-  if (expecting_root_surface_damage_because_of_resize_) {
-    TRACE_EVENT_INSTANT0("cc", "Entire display damaged",
-                         TRACE_EVENT_SCOPE_THREAD);
-    return BeginFrameDeadlineMode::kLate;
-  }
-
-  TRACE_EVENT_INSTANT0("cc", "More damage expected soon",
-                       TRACE_EVENT_SCOPE_THREAD);
-  return BeginFrameDeadlineMode::kRegular;
-}
-
-void DisplayScheduler::ScheduleBeginFrameDeadline() {
-  TRACE_EVENT0("cc", "DisplayScheduler::ScheduleBeginFrameDeadline");
-
-  // We need to wait for the next BeginFrame before scheduling a deadline.
-  if (!inside_begin_frame_deadline_interval_) {
-    TRACE_EVENT_INSTANT0("cc", "Waiting for next BeginFrame",
-                         TRACE_EVENT_SCOPE_THREAD);
-    DCHECK(begin_frame_deadline_task_.IsCancelled());
-    return;
-  }
-
-  // Determine the deadline we want to use.
-  base::TimeTicks desired_deadline = DesiredBeginFrameDeadlineTime();
-
-  // Avoid re-scheduling the deadline if it's already correctly scheduled.
-  if (!begin_frame_deadline_task_.IsCancelled() &&
-      desired_deadline == begin_frame_deadline_task_time_) {
-    TRACE_EVENT_INSTANT0("cc", "Using existing deadline",
-                         TRACE_EVENT_SCOPE_THREAD);
-    return;
-  }
-
-  // Schedule the deadline.
-  begin_frame_deadline_task_time_ = desired_deadline;
-  begin_frame_deadline_task_.Cancel();
-
-  if (begin_frame_deadline_task_time_ == base::TimeTicks::Max()) {
-    TRACE_EVENT_INSTANT0("cc", "Using infinite deadline",
-                         TRACE_EVENT_SCOPE_THREAD);
-    return;
-  }
-
-  begin_frame_deadline_task_.Reset(begin_frame_deadline_closure_);
-  base::TimeDelta delta =
-      std::max(base::TimeDelta(), desired_deadline - base::TimeTicks::Now());
-  task_runner_->PostDelayedTask(FROM_HERE,
-                                begin_frame_deadline_task_.callback(), delta);
-  TRACE_EVENT2("cc", "Using new deadline", "delta", delta.ToInternalValue(),
-               "desired_deadline", desired_deadline);
-}
-
-bool DisplayScheduler::AttemptDrawAndSwap() {
-  inside_begin_frame_deadline_interval_ = false;
-  begin_frame_deadline_task_.Cancel();
-  begin_frame_deadline_task_time_ = base::TimeTicks();
-
-  if (ShouldDraw()) {
-    if (pending_swaps_ < max_pending_swaps_ && !root_surface_resources_locked_)
-      return DrawAndSwap();
-  } else {
-    // We are going idle, so reset expectations.
-    // TODO(eseckler): Should we avoid going idle if
-    // |expecting_root_surface_damage_because_of_resize_| is true?
-    expecting_root_surface_damage_because_of_resize_ = false;
-
-    StopObservingBeginFrames();
-  }
-  return false;
-}
-
-void DisplayScheduler::OnBeginFrameDeadline() {
-  TRACE_EVENT0("cc", "DisplayScheduler::OnBeginFrameDeadline");
-  DCHECK(inside_begin_frame_deadline_interval_);
-
-  bool did_draw = AttemptDrawAndSwap();
-  DidFinishFrame(did_draw);
-}
-
-void DisplayScheduler::DidFinishFrame(bool did_draw) {
-  DCHECK(begin_frame_source_);
-  // TODO(eseckler): Let client know that frame was completed.
-  begin_frame_source_->DidFinishFrame(this);
-}
-
-void DisplayScheduler::DidSwapBuffers() {
-  pending_swaps_++;
-  uint32_t swap_id = next_swap_id_++;
-  TRACE_EVENT_ASYNC_BEGIN0("cc", "DisplayScheduler:pending_swaps", swap_id);
-}
-
-void DisplayScheduler::DidReceiveSwapBuffersAck() {
-  uint32_t swap_id = next_swap_id_ - pending_swaps_;
-  pending_swaps_--;
-  TRACE_EVENT_ASYNC_END0("cc", "DisplayScheduler:pending_swaps", swap_id);
-  ScheduleBeginFrameDeadline();
-}
-
-}  // namespace cc
diff --git a/cc/surfaces/display_scheduler.h b/cc/surfaces/display_scheduler.h
deleted file mode 100644
index 0979580..0000000
--- a/cc/surfaces/display_scheduler.h
+++ /dev/null
@@ -1,137 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_SURFACES_DISPLAY_SCHEDULER_H_
-#define CC_SURFACES_DISPLAY_SCHEDULER_H_
-
-#include <memory>
-
-#include "base/cancelable_callback.h"
-#include "base/containers/flat_map.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "base/single_thread_task_runner.h"
-#include "cc/output/renderer_settings.h"
-#include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/surface_observer.h"
-#include "cc/surfaces/surfaces_export.h"
-#include "components/viz/common/surface_id.h"
-
-namespace cc {
-
-class BeginFrameSource;
-class SurfaceInfo;
-
-class CC_SURFACES_EXPORT DisplaySchedulerClient {
- public:
-  virtual ~DisplaySchedulerClient() {}
-
-  virtual bool DrawAndSwap() = 0;
-  virtual bool SurfaceHasUndrawnFrame(
-      const viz::SurfaceId& surface_id) const = 0;
-  virtual bool SurfaceDamaged(const viz::SurfaceId& surface_id,
-                              const BeginFrameAck& ack) = 0;
-  virtual void SurfaceDiscarded(const viz::SurfaceId& surface_id) = 0;
-};
-
-class CC_SURFACES_EXPORT DisplayScheduler : public BeginFrameObserverBase,
-                                            public SurfaceObserver {
- public:
-  DisplayScheduler(BeginFrameSource* begin_frame_source,
-                   base::SingleThreadTaskRunner* task_runner,
-                   int max_pending_swaps,
-                   bool wait_for_all_surfaces_before_draw = false);
-  ~DisplayScheduler() override;
-
-  void SetClient(DisplaySchedulerClient* client);
-
-  void SetVisible(bool visible);
-  void SetRootSurfaceResourcesLocked(bool locked);
-  void ForceImmediateSwapIfPossible();
-  virtual void DisplayResized();
-  virtual void SetNewRootSurface(const viz::SurfaceId& root_surface_id);
-  virtual void ProcessSurfaceDamage(const viz::SurfaceId& surface_id,
-                                    const BeginFrameAck& ack,
-                                    bool display_damaged);
-
-  virtual void DidSwapBuffers();
-  void DidReceiveSwapBuffersAck();
-
-  void OutputSurfaceLost();
-
-  // BeginFrameObserverBase implementation.
-  bool OnBeginFrameDerivedImpl(const BeginFrameArgs& args) override;
-  void OnBeginFrameSourcePausedChanged(bool paused) override;
-
-  // SurfaceObserver implementation.
-  void OnSurfaceCreated(const SurfaceInfo& surface_info) override;
-  void OnSurfaceDestroyed(const viz::SurfaceId& surface_id) override;
-  bool OnSurfaceDamaged(const viz::SurfaceId& surface_id,
-                        const BeginFrameAck& ack) override;
-  void OnSurfaceDiscarded(const viz::SurfaceId& surface_id) override;
-  void OnSurfaceDamageExpected(const viz::SurfaceId& surface_id,
-                               const BeginFrameArgs& args) override;
-  void OnSurfaceWillDraw(const viz::SurfaceId& surface_id) override;
-
- protected:
-  enum class BeginFrameDeadlineMode { kImmediate, kRegular, kLate, kNone };
-  base::TimeTicks DesiredBeginFrameDeadlineTime() const;
-  BeginFrameDeadlineMode AdjustedBeginFrameDeadlineMode() const;
-  BeginFrameDeadlineMode DesiredBeginFrameDeadlineMode() const;
-  virtual void ScheduleBeginFrameDeadline();
-  bool AttemptDrawAndSwap();
-  void OnBeginFrameDeadline();
-  bool DrawAndSwap();
-  void StartObservingBeginFrames();
-  void StopObservingBeginFrames();
-  bool ShouldDraw();
-  void DidFinishFrame(bool did_draw);
-  // Updates |has_pending_surfaces_| and returns whether its value changed.
-  bool UpdateHasPendingSurfaces();
-
-  DisplaySchedulerClient* client_;
-  BeginFrameSource* begin_frame_source_;
-  base::SingleThreadTaskRunner* task_runner_;
-
-  BeginFrameArgs current_begin_frame_args_;
-  base::Closure begin_frame_deadline_closure_;
-  base::CancelableClosure begin_frame_deadline_task_;
-  base::TimeTicks begin_frame_deadline_task_time_;
-
-  base::CancelableClosure missed_begin_frame_task_;
-  bool inside_surface_damaged_;
-
-  bool visible_;
-  bool output_surface_lost_;
-  bool root_surface_resources_locked_;
-
-  bool inside_begin_frame_deadline_interval_;
-  bool needs_draw_;
-  bool expecting_root_surface_damage_because_of_resize_;
-  bool has_pending_surfaces_;
-
-  struct SurfaceBeginFrameState {
-    BeginFrameArgs last_args;
-    BeginFrameAck last_ack;
-  };
-  base::flat_map<viz::SurfaceId, SurfaceBeginFrameState> surface_states_;
-
-  int next_swap_id_;
-  int pending_swaps_;
-  int max_pending_swaps_;
-  bool wait_for_all_surfaces_before_draw_;
-
-  bool observing_begin_frame_source_;
-
-  viz::SurfaceId root_surface_id_;
-
-  base::WeakPtrFactory<DisplayScheduler> weak_ptr_factory_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(DisplayScheduler);
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_DISPLAY_SCHEDULER_H_
diff --git a/cc/surfaces/display_scheduler_unittest.cc b/cc/surfaces/display_scheduler_unittest.cc
deleted file mode 100644
index 473ee26..0000000
--- a/cc/surfaces/display_scheduler_unittest.cc
+++ /dev/null
@@ -1,735 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/surfaces/display_scheduler.h"
-
-#include "base/logging.h"
-#include "base/stl_util.h"
-#include "base/test/null_task_runner.h"
-#include "base/test/simple_test_tick_clock.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/output/begin_frame_args.h"
-#include "cc/surfaces/display.h"
-#include "cc/surfaces/surface_info.h"
-#include "cc/test/fake_external_begin_frame_source.h"
-#include "cc/test/scheduler_test_common.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-const int kMaxPendingSwaps = 1;
-
-static constexpr viz::FrameSinkId kArbitraryFrameSinkId(1, 1);
-
-class FakeDisplaySchedulerClient : public DisplaySchedulerClient {
- public:
-  FakeDisplaySchedulerClient()
-      : draw_and_swap_count_(0), next_draw_and_swap_fails_(false) {}
-
-  ~FakeDisplaySchedulerClient() override {}
-
-  bool DrawAndSwap() override {
-    draw_and_swap_count_++;
-
-    bool success = !next_draw_and_swap_fails_;
-    next_draw_and_swap_fails_ = false;
-
-    if (success)
-      undrawn_surfaces_.clear();
-    return success;
-  }
-
-  bool SurfaceHasUndrawnFrame(const viz::SurfaceId& surface_id) const override {
-    return base::ContainsKey(undrawn_surfaces_, surface_id);
-  }
-
-  bool SurfaceDamaged(const viz::SurfaceId& surface_id,
-                      const BeginFrameAck& ack) override {
-    return false;
-  }
-
-  void SurfaceDiscarded(const viz::SurfaceId& surface_id) override {}
-
-  int draw_and_swap_count() const { return draw_and_swap_count_; }
-
-  void SetNextDrawAndSwapFails() { next_draw_and_swap_fails_ = true; }
-
-  void SurfaceDamaged(const viz::SurfaceId& surface_id) {
-    undrawn_surfaces_.insert(surface_id);
-  }
-
- protected:
-  int draw_and_swap_count_;
-  bool next_draw_and_swap_fails_;
-  std::set<viz::SurfaceId> undrawn_surfaces_;
-};
-
-class TestDisplayScheduler : public DisplayScheduler {
- public:
-  TestDisplayScheduler(BeginFrameSource* begin_frame_source,
-                       SurfaceManager* surface_manager,
-                       base::SingleThreadTaskRunner* task_runner,
-                       int max_pending_swaps,
-                       bool wait_for_all_surfaces_before_draw)
-      : DisplayScheduler(begin_frame_source,
-                         task_runner,
-                         max_pending_swaps,
-                         wait_for_all_surfaces_before_draw),
-        scheduler_begin_frame_deadline_count_(0) {}
-
-  base::TimeTicks DesiredBeginFrameDeadlineTimeForTest() {
-    return DesiredBeginFrameDeadlineTime();
-  }
-
-  void BeginFrameDeadlineForTest() {
-    // Ensure that any missed BeginFrames were handled by the scheduler. We need
-    // to run the scheduled task ourselves since the NullTaskRunner won't.
-    if (!missed_begin_frame_task_.IsCancelled())
-      missed_begin_frame_task_.callback().Run();
-    OnBeginFrameDeadline();
-  }
-
-  void ScheduleBeginFrameDeadline() override {
-    scheduler_begin_frame_deadline_count_++;
-    DisplayScheduler::ScheduleBeginFrameDeadline();
-  }
-
-  int scheduler_begin_frame_deadline_count() {
-    return scheduler_begin_frame_deadline_count_;
-  }
-
-  bool inside_begin_frame_deadline_interval() {
-    return inside_begin_frame_deadline_interval_;
-  }
-
-  bool has_pending_surfaces() { return has_pending_surfaces_; }
-
- protected:
-  int scheduler_begin_frame_deadline_count_;
-};
-
-class DisplaySchedulerTest : public testing::Test {
- public:
-  explicit DisplaySchedulerTest(bool wait_for_all_surfaces_before_draw = false)
-      : fake_begin_frame_source_(0.f, false),
-        task_runner_(new base::NullTaskRunner),
-        scheduler_(&fake_begin_frame_source_,
-                   &surface_manager_,
-                   task_runner_.get(),
-                   kMaxPendingSwaps,
-                   wait_for_all_surfaces_before_draw) {
-    now_src_.Advance(base::TimeDelta::FromMicroseconds(10000));
-    surface_manager_.AddObserver(&scheduler_);
-    scheduler_.SetClient(&client_);
-  }
-
-  ~DisplaySchedulerTest() override {
-    surface_manager_.RemoveObserver(&scheduler_);
-  }
-
-  void SetUp() override { scheduler_.SetRootSurfaceResourcesLocked(false); }
-
-  void AdvanceTimeAndBeginFrameForTest(
-      const std::vector<viz::SurfaceId>& observing_surfaces) {
-    now_src_.Advance(base::TimeDelta::FromMicroseconds(10000));
-    // FakeBeginFrameSource deals with |source_id| and |sequence_number|.
-    last_begin_frame_args_ = fake_begin_frame_source_.CreateBeginFrameArgs(
-        BEGINFRAME_FROM_HERE, &now_src_);
-    fake_begin_frame_source_.TestOnBeginFrame(last_begin_frame_args_);
-    for (const viz::SurfaceId& surface : observing_surfaces)
-      scheduler_.OnSurfaceDamageExpected(surface, last_begin_frame_args_);
-  }
-
-  void SurfaceDamaged(const viz::SurfaceId& surface_id) {
-    client_.SurfaceDamaged(surface_id);
-    scheduler_.ProcessSurfaceDamage(surface_id, AckForCurrentBeginFrame(),
-                                    true);
-  }
-
- protected:
-  base::SimpleTestTickClock& now_src() { return now_src_; }
-  FakeDisplaySchedulerClient& client() { return client_; }
-  DisplayScheduler& scheduler() { return scheduler_; }
-  BeginFrameAck AckForCurrentBeginFrame() {
-    DCHECK(last_begin_frame_args_.IsValid());
-    return BeginFrameAck(last_begin_frame_args_.source_id,
-                         last_begin_frame_args_.sequence_number,
-                         last_begin_frame_args_.sequence_number, true);
-  }
-
-  FakeExternalBeginFrameSource fake_begin_frame_source_;
-  BeginFrameArgs last_begin_frame_args_;
-
-  base::SimpleTestTickClock now_src_;
-  scoped_refptr<base::NullTaskRunner> task_runner_;
-  SurfaceManager surface_manager_;
-  FakeDisplaySchedulerClient client_;
-  TestDisplayScheduler scheduler_;
-};
-
-TEST_F(DisplaySchedulerTest, ResizeHasLateDeadlineUntilNewRootSurface) {
-  viz::SurfaceId root_surface_id1(
-      kArbitraryFrameSinkId,
-      viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
-  viz::SurfaceId root_surface_id2(
-      kArbitraryFrameSinkId,
-      viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
-  viz::SurfaceId sid1(kArbitraryFrameSinkId,
-                      viz::LocalSurfaceId(3, base::UnguessableToken::Create()));
-  base::TimeTicks late_deadline;
-
-  scheduler_.SetVisible(true);
-
-  // Go trough an initial BeginFrame cycle with the root surface.
-  AdvanceTimeAndBeginFrameForTest(std::vector<viz::SurfaceId>());
-  scheduler_.SetNewRootSurface(root_surface_id1);
-  scheduler_.BeginFrameDeadlineForTest();
-
-  // Resize on the next begin frame cycle should cause the deadline to wait
-  // for a new root surface.
-  AdvanceTimeAndBeginFrameForTest({root_surface_id1});
-  late_deadline = now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
-  SurfaceDamaged(sid1);
-  EXPECT_GT(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.DisplayResized();
-  EXPECT_EQ(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.OnSurfaceDestroyed(root_surface_id1);
-  scheduler_.SetNewRootSurface(root_surface_id2);
-  EXPECT_GE(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.BeginFrameDeadlineForTest();
-
-  // Verify deadline goes back to normal after resize.
-  late_deadline = now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
-  AdvanceTimeAndBeginFrameForTest({root_surface_id2, sid1});
-  SurfaceDamaged(sid1);
-  EXPECT_GT(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  SurfaceDamaged(root_surface_id2);
-  EXPECT_GE(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.BeginFrameDeadlineForTest();
-}
-
-TEST_F(DisplaySchedulerTest, ResizeHasLateDeadlineUntilDamagedSurface) {
-  viz::SurfaceId root_surface_id(
-      kArbitraryFrameSinkId,
-      viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
-  viz::SurfaceId sid1(kArbitraryFrameSinkId,
-                      viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
-  base::TimeTicks late_deadline;
-
-  scheduler_.SetVisible(true);
-
-  // Go trough an initial BeginFrame cycle with the root surface.
-  AdvanceTimeAndBeginFrameForTest(std::vector<viz::SurfaceId>());
-  scheduler_.SetNewRootSurface(root_surface_id);
-  scheduler_.BeginFrameDeadlineForTest();
-
-  // Resize on the next begin frame cycle should cause the deadline to wait
-  // for a new root surface.
-  AdvanceTimeAndBeginFrameForTest({root_surface_id});
-  late_deadline = now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
-  SurfaceDamaged(sid1);
-  EXPECT_GT(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.DisplayResized();
-  EXPECT_EQ(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  SurfaceDamaged(root_surface_id);
-  EXPECT_GE(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.BeginFrameDeadlineForTest();
-
-  // Verify deadline goes back to normal after resize.
-  AdvanceTimeAndBeginFrameForTest({root_surface_id, sid1});
-  late_deadline = now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
-  SurfaceDamaged(sid1);
-  EXPECT_GT(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  SurfaceDamaged(root_surface_id);
-  EXPECT_GE(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.BeginFrameDeadlineForTest();
-}
-
-TEST_F(DisplaySchedulerTest, SurfaceDamaged) {
-  viz::SurfaceId root_surface_id(
-      kArbitraryFrameSinkId,
-      viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
-  viz::SurfaceId sid1(kArbitraryFrameSinkId,
-                      viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
-  viz::SurfaceId sid2(kArbitraryFrameSinkId,
-                      viz::LocalSurfaceId(3, base::UnguessableToken::Create()));
-
-  scheduler_.SetVisible(true);
-  scheduler_.SetNewRootSurface(root_surface_id);
-
-  // Set surface1 as active via SurfaceDamageExpected().
-  AdvanceTimeAndBeginFrameForTest({sid1});
-
-  // Damage only from surface 2 (inactive) does not trigger deadline early.
-  SurfaceDamaged(sid2);
-  EXPECT_TRUE(scheduler_.has_pending_surfaces());
-  EXPECT_LT(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-
-  // Damage from surface 1 triggers deadline early.
-  SurfaceDamaged(sid1);
-  EXPECT_FALSE(scheduler_.has_pending_surfaces());
-  EXPECT_GE(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.BeginFrameDeadlineForTest();
-
-  // Set both surface 1 and 2 as active via SurfaceDamageExpected().
-  AdvanceTimeAndBeginFrameForTest({sid1, sid2});
-
-  // Deadline doesn't trigger early until surface 1 and 2 are both damaged.
-  EXPECT_LT(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  SurfaceDamaged(sid1);
-  EXPECT_LT(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  SurfaceDamaged(sid2);
-  EXPECT_GE(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.BeginFrameDeadlineForTest();
-
-  // Surface damage with |!has_damage| triggers early deadline if other damage
-  // exists.
-  AdvanceTimeAndBeginFrameForTest({sid1, sid2});
-  EXPECT_LT(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  SurfaceDamaged(sid2);
-  EXPECT_LT(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  BeginFrameAck ack = AckForCurrentBeginFrame();
-  ack.has_damage = false;
-  scheduler_.ProcessSurfaceDamage(sid1, ack, false);
-  EXPECT_GE(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.BeginFrameDeadlineForTest();
-
-  // Surface damage with |!has_damage| does not trigger early deadline if no
-  // other damage exists.
-  AdvanceTimeAndBeginFrameForTest({sid1});
-  EXPECT_LT(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  ack = AckForCurrentBeginFrame();
-  ack.has_damage = false;
-  scheduler_.ProcessSurfaceDamage(sid1, ack, false);
-  EXPECT_LT(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.BeginFrameDeadlineForTest();
-
-  // System should be idle now.
-  AdvanceTimeAndBeginFrameForTest(std::vector<viz::SurfaceId>());
-  EXPECT_FALSE(scheduler_.inside_begin_frame_deadline_interval());
-
-  // Surface damage with |!display_damaged| does not affect needs_draw and
-  // scheduler stays idle.
-  scheduler_.ProcessSurfaceDamage(sid1, AckForCurrentBeginFrame(), false);
-  EXPECT_FALSE(scheduler_.inside_begin_frame_deadline_interval());
-
-  // Deadline should trigger early if child surfaces are idle and
-  // we get damage on the root surface.
-  scheduler_.OnSurfaceDamageExpected(root_surface_id, last_begin_frame_args_);
-  EXPECT_FALSE(scheduler_.inside_begin_frame_deadline_interval());
-  SurfaceDamaged(root_surface_id);
-  EXPECT_GE(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.BeginFrameDeadlineForTest();
-}
-
-class DisplaySchedulerWaitForAllSurfacesTest : public DisplaySchedulerTest {
- public:
-  DisplaySchedulerWaitForAllSurfacesTest()
-      : DisplaySchedulerTest(true /* wait_for_all_surfaces_before_draw */) {}
-};
-
-TEST_F(DisplaySchedulerWaitForAllSurfacesTest, WaitForAllSurfacesBeforeDraw) {
-  viz::SurfaceId root_surface_id(
-      kArbitraryFrameSinkId,
-      viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
-  viz::SurfaceId sid1(kArbitraryFrameSinkId,
-                      viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
-  viz::SurfaceId sid2(kArbitraryFrameSinkId,
-                      viz::LocalSurfaceId(3, base::UnguessableToken::Create()));
-
-  scheduler_.SetVisible(true);
-  scheduler_.SetNewRootSurface(root_surface_id);
-
-  // Set surface1 as active via SurfaceDamageExpected().
-  AdvanceTimeAndBeginFrameForTest({sid1});
-
-  // Deadline is blocked indefinitely until surface 1 is damaged.
-  EXPECT_EQ(base::TimeTicks::Max(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-
-  // Damage only from surface 2 (inactive) does not change deadline.
-  SurfaceDamaged(sid2);
-  EXPECT_TRUE(scheduler_.has_pending_surfaces());
-  EXPECT_EQ(base::TimeTicks::Max(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-
-  // Damage from surface 1 triggers deadline immediately.
-  SurfaceDamaged(sid1);
-  EXPECT_FALSE(scheduler_.has_pending_surfaces());
-  EXPECT_GE(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.BeginFrameDeadlineForTest();
-
-  // Surface damage with |!has_damage| triggers immediate deadline if other
-  // damage exists.
-  AdvanceTimeAndBeginFrameForTest({sid1, sid2});
-  EXPECT_EQ(base::TimeTicks::Max(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  SurfaceDamaged(sid2);
-  EXPECT_EQ(base::TimeTicks::Max(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  BeginFrameAck ack = AckForCurrentBeginFrame();
-  ack.has_damage = false;
-  scheduler_.ProcessSurfaceDamage(sid1, ack, false);
-  EXPECT_GE(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.BeginFrameDeadlineForTest();
-
-  // Surface damage with |!has_damage| also triggers immediate deadline even if
-  // no other damage exists.
-  AdvanceTimeAndBeginFrameForTest({sid1});
-  EXPECT_EQ(base::TimeTicks::Max(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  ack = AckForCurrentBeginFrame();
-  ack.has_damage = false;
-  scheduler_.ProcessSurfaceDamage(sid1, ack, false);
-  EXPECT_GE(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.BeginFrameDeadlineForTest();
-
-  // System should be idle now because we had a frame without damage. Restore it
-  // to active state (DisplayScheduler observing BeginFrames) for the next test.
-  AdvanceTimeAndBeginFrameForTest(std::vector<viz::SurfaceId>());
-  EXPECT_FALSE(scheduler_.inside_begin_frame_deadline_interval());
-  SurfaceDamaged(sid1);
-  scheduler_.BeginFrameDeadlineForTest();
-
-  // BeginFrame without expected surface damage triggers immediate deadline.
-  AdvanceTimeAndBeginFrameForTest(std::vector<viz::SurfaceId>());
-  EXPECT_TRUE(scheduler_.inside_begin_frame_deadline_interval());
-  EXPECT_GE(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.BeginFrameDeadlineForTest();
-}
-
-TEST_F(DisplaySchedulerTest, OutputSurfaceLost) {
-  viz::SurfaceId root_surface_id(
-      kArbitraryFrameSinkId,
-      viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
-  viz::SurfaceId sid1(kArbitraryFrameSinkId,
-                      viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
-
-  scheduler_.SetVisible(true);
-  scheduler_.SetNewRootSurface(root_surface_id);
-
-  // DrawAndSwap normally.
-  AdvanceTimeAndBeginFrameForTest({sid1});
-  EXPECT_LT(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  EXPECT_EQ(0, client_.draw_and_swap_count());
-  SurfaceDamaged(sid1);
-  scheduler_.BeginFrameDeadlineForTest();
-  EXPECT_EQ(1, client_.draw_and_swap_count());
-
-  // Deadline triggers immediately on OutputSurfaceLost.
-  AdvanceTimeAndBeginFrameForTest({sid1});
-  EXPECT_LT(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.OutputSurfaceLost();
-  EXPECT_GE(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-
-  // Deadline does not DrawAndSwap after OutputSurfaceLost.
-  EXPECT_EQ(1, client_.draw_and_swap_count());
-  SurfaceDamaged(sid1);
-  scheduler_.BeginFrameDeadlineForTest();
-  EXPECT_EQ(1, client_.draw_and_swap_count());
-}
-
-TEST_F(DisplaySchedulerTest, VisibleWithoutDamageNoTicks) {
-  viz::SurfaceId root_surface_id(
-      kArbitraryFrameSinkId,
-      viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
-
-  EXPECT_EQ(0u, fake_begin_frame_source_.num_observers());
-  scheduler_.SetVisible(true);
-
-  // When becoming visible, don't start listening for begin frames until there
-  // is some damage.
-  EXPECT_EQ(0u, fake_begin_frame_source_.num_observers());
-  scheduler_.SetNewRootSurface(root_surface_id);
-
-  EXPECT_EQ(1u, fake_begin_frame_source_.num_observers());
-}
-
-TEST_F(DisplaySchedulerTest, VisibleWithDamageTicks) {
-  viz::SurfaceId root_surface_id(
-      kArbitraryFrameSinkId,
-      viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
-  viz::SurfaceId sid1(kArbitraryFrameSinkId,
-                      viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
-
-  scheduler_.SetNewRootSurface(root_surface_id);
-
-  // When there is damage, start listening for begin frames once becoming
-  // visible.
-  EXPECT_EQ(0u, fake_begin_frame_source_.num_observers());
-  scheduler_.SetVisible(true);
-
-  EXPECT_EQ(1u, fake_begin_frame_source_.num_observers());
-}
-
-TEST_F(DisplaySchedulerTest, Visibility) {
-  viz::SurfaceId root_surface_id(
-      kArbitraryFrameSinkId,
-      viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
-  viz::SurfaceId sid1(kArbitraryFrameSinkId,
-                      viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
-
-  // Set the root surface.
-  scheduler_.SetNewRootSurface(root_surface_id);
-  scheduler_.SetVisible(true);
-  EXPECT_EQ(1u, fake_begin_frame_source_.num_observers());
-
-  // DrawAndSwap normally.
-  AdvanceTimeAndBeginFrameForTest({sid1});
-  EXPECT_LT(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  EXPECT_EQ(0, client_.draw_and_swap_count());
-  SurfaceDamaged(sid1);
-  scheduler_.BeginFrameDeadlineForTest();
-  EXPECT_EQ(1, client_.draw_and_swap_count());
-
-  AdvanceTimeAndBeginFrameForTest({sid1});
-  EXPECT_LT(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-
-  // Become not visible.
-  scheduler_.SetVisible(false);
-
-  // It will stop listening for begin frames after the current deadline.
-  EXPECT_EQ(1u, fake_begin_frame_source_.num_observers());
-
-  // Deadline does not DrawAndSwap when not visible.
-  EXPECT_EQ(1, client_.draw_and_swap_count());
-  scheduler_.BeginFrameDeadlineForTest();
-  EXPECT_EQ(1, client_.draw_and_swap_count());
-  // Now it stops listening for begin frames.
-  EXPECT_EQ(0u, fake_begin_frame_source_.num_observers());
-
-  // Does not start listening for begin frames when becoming visible without
-  // damage.
-  scheduler_.SetVisible(true);
-  EXPECT_EQ(0u, fake_begin_frame_source_.num_observers());
-  scheduler_.SetVisible(false);
-
-  // Does not start listening for begin frames when damage arrives.
-  SurfaceDamaged(sid1);
-  EXPECT_EQ(0u, fake_begin_frame_source_.num_observers());
-
-  // But does when becoming visible with damage again.
-  scheduler_.SetVisible(true);
-  EXPECT_EQ(1u, fake_begin_frame_source_.num_observers());
-}
-
-TEST_F(DisplaySchedulerTest, ResizeCausesSwap) {
-  viz::SurfaceId root_surface_id(
-      kArbitraryFrameSinkId,
-      viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
-  viz::SurfaceId sid1(kArbitraryFrameSinkId,
-                      viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
-
-  scheduler_.SetVisible(true);
-  scheduler_.SetNewRootSurface(root_surface_id);
-
-  // DrawAndSwap normally.
-  AdvanceTimeAndBeginFrameForTest({sid1});
-  EXPECT_LT(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  EXPECT_EQ(0, client_.draw_and_swap_count());
-  SurfaceDamaged(sid1);
-  scheduler_.BeginFrameDeadlineForTest();
-  EXPECT_EQ(1, client_.draw_and_swap_count());
-
-  scheduler_.DisplayResized();
-  AdvanceTimeAndBeginFrameForTest(std::vector<viz::SurfaceId>());
-  // DisplayResized should trigger a swap to happen.
-  scheduler_.BeginFrameDeadlineForTest();
-  EXPECT_EQ(2, client_.draw_and_swap_count());
-}
-
-TEST_F(DisplaySchedulerTest, RootSurfaceResourcesLocked) {
-  viz::SurfaceId root_surface_id(
-      kArbitraryFrameSinkId,
-      viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
-  viz::SurfaceId sid1(kArbitraryFrameSinkId,
-                      viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
-  base::TimeTicks late_deadline;
-
-  scheduler_.SetVisible(true);
-  scheduler_.SetNewRootSurface(root_surface_id);
-
-  // DrawAndSwap normally.
-  AdvanceTimeAndBeginFrameForTest({sid1});
-  EXPECT_LT(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  EXPECT_EQ(0, client_.draw_and_swap_count());
-  SurfaceDamaged(sid1);
-  scheduler_.BeginFrameDeadlineForTest();
-  EXPECT_EQ(1, client_.draw_and_swap_count());
-
-  // Deadline triggers late while root resources are locked.
-  AdvanceTimeAndBeginFrameForTest({sid1});
-  late_deadline = now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
-  SurfaceDamaged(sid1);
-  EXPECT_GT(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.SetRootSurfaceResourcesLocked(true);
-  EXPECT_EQ(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-
-  // Deadline does not DrawAndSwap while root resources are locked.
-  EXPECT_EQ(1, client_.draw_and_swap_count());
-  SurfaceDamaged(sid1);
-  scheduler_.BeginFrameDeadlineForTest();
-  EXPECT_EQ(1, client_.draw_and_swap_count());
-
-  //  Deadline triggers normally when root resources are unlocked.
-  AdvanceTimeAndBeginFrameForTest({sid1, root_surface_id});
-  late_deadline = now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
-  SurfaceDamaged(sid1);
-  EXPECT_EQ(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  scheduler_.SetRootSurfaceResourcesLocked(false);
-  SurfaceDamaged(root_surface_id);
-  EXPECT_EQ(base::TimeTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-
-  EXPECT_EQ(1, client_.draw_and_swap_count());
-  scheduler_.BeginFrameDeadlineForTest();
-  EXPECT_EQ(2, client_.draw_and_swap_count());
-}
-
-TEST_F(DisplaySchedulerTest, DidSwapBuffers) {
-  viz::SurfaceId root_surface_id(
-      kArbitraryFrameSinkId,
-      viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
-  viz::SurfaceId sid1(kArbitraryFrameSinkId,
-                      viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
-  viz::SurfaceId sid2(kArbitraryFrameSinkId,
-                      viz::LocalSurfaceId(3, base::UnguessableToken::Create()));
-
-  scheduler_.SetVisible(true);
-  scheduler_.SetNewRootSurface(root_surface_id);
-
-  // Set surface 1 and 2 as active.
-  AdvanceTimeAndBeginFrameForTest({sid1, sid2});
-
-  // DrawAndSwap normally.
-  EXPECT_LT(now_src().NowTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  EXPECT_EQ(0, client_.draw_and_swap_count());
-  SurfaceDamaged(sid1);
-  SurfaceDamaged(sid2);
-  scheduler_.BeginFrameDeadlineForTest();
-  EXPECT_EQ(1, client_.draw_and_swap_count());
-  scheduler_.DidSwapBuffers();
-
-  // Deadline triggers late when swap throttled.
-  AdvanceTimeAndBeginFrameForTest({sid1, sid2});
-  base::TimeTicks late_deadline =
-      now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
-  // Damage surface 1, but not surface 2 so we avoid triggering deadline
-  // early because all surfaces are ready.
-  SurfaceDamaged(sid1);
-  EXPECT_EQ(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-
-  // Don't draw and swap in deadline while swap throttled.
-  EXPECT_EQ(1, client_.draw_and_swap_count());
-  scheduler_.BeginFrameDeadlineForTest();
-  EXPECT_EQ(1, client_.draw_and_swap_count());
-
-  // Deadline triggers normally once not swap throttled.
-  // Damage from previous BeginFrame should cary over, so don't damage again.
-  scheduler_.DidReceiveSwapBuffersAck();
-  AdvanceTimeAndBeginFrameForTest({sid2});
-  base::TimeTicks expected_deadline =
-      scheduler_.LastUsedBeginFrameArgs().deadline -
-      BeginFrameArgs::DefaultEstimatedParentDrawTime();
-  EXPECT_EQ(expected_deadline,
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  // Still waiting for surface 2. Once it updates, deadline should trigger
-  // immediately again.
-  SurfaceDamaged(sid2);
-  EXPECT_EQ(base::TimeTicks(),
-            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
-  // Draw and swap now that we aren't throttled.
-  EXPECT_EQ(1, client_.draw_and_swap_count());
-  scheduler_.BeginFrameDeadlineForTest();
-  EXPECT_EQ(2, client_.draw_and_swap_count());
-}
-
-// This test verfies that we try to reschedule the deadline
-// after any event that may change what deadline we want.
-TEST_F(DisplaySchedulerTest, ScheduleBeginFrameDeadline) {
-  viz::SurfaceId root_surface_id(
-      kArbitraryFrameSinkId,
-      viz::LocalSurfaceId(1, base::UnguessableToken::Create()));
-  viz::SurfaceId sid1(kArbitraryFrameSinkId,
-                      viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
-  int count = 1;
-  EXPECT_EQ(count, scheduler_.scheduler_begin_frame_deadline_count());
-
-  scheduler_.SetVisible(true);
-  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
-
-  scheduler_.SetVisible(true);
-  EXPECT_EQ(count, scheduler_.scheduler_begin_frame_deadline_count());
-
-  scheduler_.SetVisible(false);
-  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
-
-  // Set the root surface while not visible.
-  scheduler_.SetNewRootSurface(root_surface_id);
-  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
-
-  scheduler_.SetVisible(true);
-  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
-
-  // Set the root surface while visible.
-  scheduler_.SetNewRootSurface(root_surface_id);
-  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
-
-  AdvanceTimeAndBeginFrameForTest(std::vector<viz::SurfaceId>());
-  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
-
-  scheduler_.BeginFrameDeadlineForTest();
-  scheduler_.DidSwapBuffers();
-  AdvanceTimeAndBeginFrameForTest(std::vector<viz::SurfaceId>());
-  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
-
-  scheduler_.DidReceiveSwapBuffersAck();
-  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
-
-  scheduler_.DisplayResized();
-  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
-
-  scheduler_.SetNewRootSurface(root_surface_id);
-  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
-
-  SurfaceDamaged(sid1);
-  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
-
-  scheduler_.SetRootSurfaceResourcesLocked(true);
-  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
-
-  scheduler_.OutputSurfaceLost();
-  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/surfaces/display_unittest.cc b/cc/surfaces/display_unittest.cc
deleted file mode 100644
index 620cd39d..0000000
--- a/cc/surfaces/display_unittest.cc
+++ /dev/null
@@ -1,657 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/surfaces/display.h"
-
-#include <utility>
-
-#include "base/memory/ptr_util.h"
-#include "base/test/null_task_runner.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/output/copy_output_result.h"
-#include "cc/output/texture_mailbox_deleter.h"
-#include "cc/quads/render_pass.h"
-#include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
-#include "cc/surfaces/display_client.h"
-#include "cc/surfaces/display_scheduler.h"
-#include "cc/surfaces/frame_sink_manager.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_manager.h"
-#include "cc/test/compositor_frame_helpers.h"
-#include "cc/test/fake_output_surface.h"
-#include "cc/test/scheduler_test_common.h"
-#include "cc/test/test_shared_bitmap_manager.h"
-#include "components/viz/common/frame_sink_id.h"
-#include "components/viz/common/local_surface_id_allocator.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
-#include "gpu/GLES2/gl2extchromium.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using testing::AnyNumber;
-
-namespace cc {
-namespace {
-
-static constexpr viz::FrameSinkId kArbitraryFrameSinkId(3, 3);
-static constexpr viz::FrameSinkId kAnotherFrameSinkId(4, 4);
-
-class TestSoftwareOutputDevice : public SoftwareOutputDevice {
- public:
-  TestSoftwareOutputDevice() {}
-
-  gfx::Rect damage_rect() const { return damage_rect_; }
-  gfx::Size viewport_pixel_size() const { return viewport_pixel_size_; }
-};
-
-class TestDisplayScheduler : public DisplayScheduler {
- public:
-  explicit TestDisplayScheduler(BeginFrameSource* begin_frame_source,
-                                base::SingleThreadTaskRunner* task_runner)
-      : DisplayScheduler(begin_frame_source, task_runner, 1),
-        damaged(false),
-        display_resized_(false),
-        has_new_root_surface(false),
-        swapped(false) {}
-
-  ~TestDisplayScheduler() override {}
-
-  void DisplayResized() override { display_resized_ = true; }
-
-  void SetNewRootSurface(const viz::SurfaceId& root_surface_id) override {
-    has_new_root_surface = true;
-  }
-
-  void ProcessSurfaceDamage(const viz::SurfaceId& surface_id,
-                            const BeginFrameAck& ack,
-                            bool display_damaged) override {
-    if (display_damaged) {
-      damaged = true;
-      needs_draw_ = true;
-    }
-  }
-
-  void DidSwapBuffers() override { swapped = true; }
-
-  void ResetDamageForTest() {
-    damaged = false;
-    display_resized_ = false;
-    has_new_root_surface = false;
-  }
-
-  bool damaged;
-  bool display_resized_;
-  bool has_new_root_surface;
-  bool swapped;
-};
-
-class DisplayTest : public testing::Test {
- public:
-  DisplayTest()
-      : support_(CompositorFrameSinkSupport::Create(
-            nullptr,
-            &manager_,
-            kArbitraryFrameSinkId,
-            true /* is_root */,
-            true /* handles_frame_sink_id_invalidation */,
-            true /* needs_sync_points */)),
-        task_runner_(new base::NullTaskRunner) {}
-
-  ~DisplayTest() override { support_->EvictCurrentSurface(); }
-
-  void SetUpDisplay(const RendererSettings& settings,
-                    std::unique_ptr<TestWebGraphicsContext3D> context) {
-    begin_frame_source_.reset(new StubBeginFrameSource);
-
-    std::unique_ptr<FakeOutputSurface> output_surface;
-    if (context) {
-      auto provider = TestContextProvider::Create(std::move(context));
-      provider->BindToCurrentThread();
-      output_surface = FakeOutputSurface::Create3d(std::move(provider));
-    } else {
-      auto device = base::MakeUnique<TestSoftwareOutputDevice>();
-      software_output_device_ = device.get();
-      output_surface = FakeOutputSurface::CreateSoftware(std::move(device));
-    }
-    output_surface_ = output_surface.get();
-    auto scheduler = base::MakeUnique<TestDisplayScheduler>(
-        begin_frame_source_.get(), task_runner_.get());
-    scheduler_ = scheduler.get();
-    display_ = CreateDisplay(settings, kArbitraryFrameSinkId,
-                             std::move(scheduler), std::move(output_surface));
-    manager_.RegisterBeginFrameSource(begin_frame_source_.get(),
-                                      kArbitraryFrameSinkId);
-  }
-
-  std::unique_ptr<Display> CreateDisplay(
-      const RendererSettings& settings,
-      const viz::FrameSinkId& frame_sink_id,
-      std::unique_ptr<DisplayScheduler> scheduler,
-      std::unique_ptr<OutputSurface> output_surface) {
-    auto display = base::MakeUnique<Display>(
-        &shared_bitmap_manager_, nullptr /* gpu_memory_buffer_manager */,
-        settings, frame_sink_id, std::move(output_surface),
-        std::move(scheduler),
-        base::MakeUnique<TextureMailboxDeleter>(task_runner_.get()));
-    display->SetVisible(true);
-    return display;
-  }
-
-  void TearDownDisplay() {
-    // Only call UnregisterBeginFrameSource if SetupDisplay has been called.
-    if (begin_frame_source_)
-      manager_.UnregisterBeginFrameSource(begin_frame_source_.get());
-  }
-
- protected:
-  void SubmitCompositorFrame(RenderPassList* pass_list,
-                             const viz::LocalSurfaceId& local_surface_id) {
-    CompositorFrame frame = test::MakeCompositorFrame();
-    pass_list->swap(frame.render_pass_list);
-
-    support_->SubmitCompositorFrame(local_surface_id, std::move(frame));
-  }
-
-  FrameSinkManager manager_;
-  std::unique_ptr<CompositorFrameSinkSupport> support_;
-  viz::LocalSurfaceIdAllocator id_allocator_;
-  scoped_refptr<base::NullTaskRunner> task_runner_;
-  TestSharedBitmapManager shared_bitmap_manager_;
-  std::unique_ptr<BeginFrameSource> begin_frame_source_;
-  std::unique_ptr<Display> display_;
-  TestSoftwareOutputDevice* software_output_device_ = nullptr;
-  FakeOutputSurface* output_surface_ = nullptr;
-  TestDisplayScheduler* scheduler_ = nullptr;
-};
-
-class StubDisplayClient : public DisplayClient {
- public:
-  void DisplayOutputSurfaceLost() override {}
-  void DisplayWillDrawAndSwap(bool will_draw_and_swap,
-                              const RenderPassList& render_passes) override {}
-  void DisplayDidDrawAndSwap() override {}
-};
-
-void CopyCallback(bool* called, std::unique_ptr<CopyOutputResult> result) {
-  *called = true;
-}
-
-// Check that frame is damaged and swapped only under correct conditions.
-TEST_F(DisplayTest, DisplayDamaged) {
-  RendererSettings settings;
-  settings.partial_swap_enabled = true;
-  settings.finish_rendering_on_resize = true;
-  SetUpDisplay(settings, nullptr);
-  gfx::ColorSpace color_space_1 = gfx::ColorSpace::CreateXYZD50();
-  gfx::ColorSpace color_space_2 = gfx::ColorSpace::CreateSCRGBLinear();
-
-  StubDisplayClient client;
-  display_->Initialize(&client, manager_.surface_manager());
-  display_->SetColorSpace(color_space_1, color_space_1);
-
-  viz::LocalSurfaceId local_surface_id(id_allocator_.GenerateId());
-  EXPECT_FALSE(scheduler_->damaged);
-  EXPECT_FALSE(scheduler_->has_new_root_surface);
-  display_->SetLocalSurfaceId(local_surface_id, 1.f);
-  EXPECT_FALSE(scheduler_->damaged);
-  EXPECT_FALSE(scheduler_->display_resized_);
-  EXPECT_TRUE(scheduler_->has_new_root_surface);
-
-  scheduler_->ResetDamageForTest();
-  display_->Resize(gfx::Size(100, 100));
-  EXPECT_FALSE(scheduler_->damaged);
-  EXPECT_TRUE(scheduler_->display_resized_);
-  EXPECT_FALSE(scheduler_->has_new_root_surface);
-
-  // First draw from surface should have full damage.
-  RenderPassList pass_list;
-  std::unique_ptr<RenderPass> pass = RenderPass::Create();
-  pass->output_rect = gfx::Rect(0, 0, 100, 100);
-  pass->damage_rect = gfx::Rect(10, 10, 1, 1);
-  pass->id = 1u;
-  pass_list.push_back(std::move(pass));
-
-  scheduler_->ResetDamageForTest();
-  SubmitCompositorFrame(&pass_list, local_surface_id);
-  EXPECT_TRUE(scheduler_->damaged);
-  EXPECT_FALSE(scheduler_->display_resized_);
-  EXPECT_FALSE(scheduler_->has_new_root_surface);
-
-  EXPECT_FALSE(scheduler_->swapped);
-  EXPECT_EQ(0u, output_surface_->num_sent_frames());
-  EXPECT_EQ(gfx::ColorSpace(), output_surface_->last_reshape_color_space());
-  display_->DrawAndSwap();
-  EXPECT_EQ(color_space_1, output_surface_->last_reshape_color_space());
-  EXPECT_TRUE(scheduler_->swapped);
-  EXPECT_EQ(1u, output_surface_->num_sent_frames());
-  EXPECT_EQ(gfx::Size(100, 100),
-            software_output_device_->viewport_pixel_size());
-  EXPECT_EQ(gfx::Rect(0, 0, 100, 100), software_output_device_->damage_rect());
-  {
-    // Only damaged portion should be swapped.
-    pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 100, 100);
-    pass->damage_rect = gfx::Rect(10, 10, 1, 1);
-    pass->id = 1u;
-
-    pass_list.push_back(std::move(pass));
-    scheduler_->ResetDamageForTest();
-    SubmitCompositorFrame(&pass_list, local_surface_id);
-    EXPECT_TRUE(scheduler_->damaged);
-    EXPECT_FALSE(scheduler_->display_resized_);
-    EXPECT_FALSE(scheduler_->has_new_root_surface);
-
-    scheduler_->swapped = false;
-    EXPECT_EQ(color_space_1, output_surface_->last_reshape_color_space());
-    display_->SetColorSpace(color_space_2, color_space_2);
-    display_->DrawAndSwap();
-    EXPECT_EQ(color_space_2, output_surface_->last_reshape_color_space());
-    EXPECT_TRUE(scheduler_->swapped);
-    EXPECT_EQ(2u, output_surface_->num_sent_frames());
-    EXPECT_EQ(gfx::Size(100, 100),
-              software_output_device_->viewport_pixel_size());
-    EXPECT_EQ(gfx::Rect(10, 10, 1, 1), software_output_device_->damage_rect());
-  }
-
-  {
-    // Pass has no damage so shouldn't be swapped.
-    pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 100, 100);
-    pass->damage_rect = gfx::Rect(10, 10, 0, 0);
-    pass->id = 1u;
-
-    pass_list.push_back(std::move(pass));
-    scheduler_->ResetDamageForTest();
-    SubmitCompositorFrame(&pass_list, local_surface_id);
-    EXPECT_TRUE(scheduler_->damaged);
-    EXPECT_FALSE(scheduler_->display_resized_);
-    EXPECT_FALSE(scheduler_->has_new_root_surface);
-
-    scheduler_->swapped = false;
-    display_->DrawAndSwap();
-    EXPECT_TRUE(scheduler_->swapped);
-    EXPECT_EQ(2u, output_surface_->num_sent_frames());
-  }
-
-  {
-    // Pass is wrong size so shouldn't be swapped.
-    pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 99, 99);
-    pass->damage_rect = gfx::Rect(10, 10, 10, 10);
-    pass->id = 1u;
-
-    local_surface_id = id_allocator_.GenerateId();
-    display_->SetLocalSurfaceId(local_surface_id, 1.f);
-
-    pass_list.push_back(std::move(pass));
-    scheduler_->ResetDamageForTest();
-    SubmitCompositorFrame(&pass_list, local_surface_id);
-    EXPECT_TRUE(scheduler_->damaged);
-    EXPECT_FALSE(scheduler_->display_resized_);
-    EXPECT_FALSE(scheduler_->has_new_root_surface);
-
-    scheduler_->swapped = false;
-    display_->DrawAndSwap();
-    EXPECT_TRUE(scheduler_->swapped);
-    EXPECT_EQ(2u, output_surface_->num_sent_frames());
-  }
-
-  {
-    // Previous frame wasn't swapped, so next swap should have full damage.
-    pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 100, 100);
-    pass->damage_rect = gfx::Rect(10, 10, 0, 0);
-    pass->id = 1u;
-
-    local_surface_id = id_allocator_.GenerateId();
-    display_->SetLocalSurfaceId(local_surface_id, 1.f);
-
-    pass_list.push_back(std::move(pass));
-    scheduler_->ResetDamageForTest();
-    SubmitCompositorFrame(&pass_list, local_surface_id);
-    EXPECT_TRUE(scheduler_->damaged);
-    EXPECT_FALSE(scheduler_->display_resized_);
-    EXPECT_FALSE(scheduler_->has_new_root_surface);
-
-    scheduler_->swapped = false;
-    display_->DrawAndSwap();
-    EXPECT_TRUE(scheduler_->swapped);
-    EXPECT_EQ(3u, output_surface_->num_sent_frames());
-    EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
-              software_output_device_->damage_rect());
-  }
-
-  {
-    // Pass has copy output request so should be swapped.
-    pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 100, 100);
-    pass->damage_rect = gfx::Rect(10, 10, 0, 0);
-    bool copy_called = false;
-    pass->copy_requests.push_back(CopyOutputRequest::CreateRequest(
-        base::Bind(&CopyCallback, &copy_called)));
-    pass->id = 1u;
-
-    pass_list.push_back(std::move(pass));
-    scheduler_->ResetDamageForTest();
-    SubmitCompositorFrame(&pass_list, local_surface_id);
-    EXPECT_TRUE(scheduler_->damaged);
-    EXPECT_FALSE(scheduler_->display_resized_);
-    EXPECT_FALSE(scheduler_->has_new_root_surface);
-
-    scheduler_->swapped = false;
-    display_->DrawAndSwap();
-    EXPECT_TRUE(scheduler_->swapped);
-    EXPECT_EQ(4u, output_surface_->num_sent_frames());
-    EXPECT_TRUE(copy_called);
-  }
-
-  // Pass has no damage, so shouldn't be swapped, but latency info should be
-  // saved for next swap.
-  {
-    pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 100, 100);
-    pass->damage_rect = gfx::Rect(10, 10, 0, 0);
-    pass->id = 1u;
-
-    pass_list.push_back(std::move(pass));
-    scheduler_->ResetDamageForTest();
-
-    CompositorFrame frame = test::MakeCompositorFrame();
-    pass_list.swap(frame.render_pass_list);
-    frame.metadata.latency_info.push_back(ui::LatencyInfo());
-
-    support_->SubmitCompositorFrame(local_surface_id, std::move(frame));
-    EXPECT_TRUE(scheduler_->damaged);
-    EXPECT_FALSE(scheduler_->display_resized_);
-    EXPECT_FALSE(scheduler_->has_new_root_surface);
-
-    scheduler_->swapped = false;
-    display_->DrawAndSwap();
-    EXPECT_TRUE(scheduler_->swapped);
-    EXPECT_EQ(4u, output_surface_->num_sent_frames());
-  }
-
-  // Resize should cause a swap if no frame was swapped at the previous size.
-  {
-    local_surface_id = id_allocator_.GenerateId();
-    display_->SetLocalSurfaceId(local_surface_id, 1.f);
-    scheduler_->swapped = false;
-    display_->Resize(gfx::Size(200, 200));
-    EXPECT_FALSE(scheduler_->swapped);
-    EXPECT_EQ(4u, output_surface_->num_sent_frames());
-
-    pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 200, 200);
-    pass->damage_rect = gfx::Rect(10, 10, 10, 10);
-    pass->id = 1u;
-
-    pass_list.push_back(std::move(pass));
-    scheduler_->ResetDamageForTest();
-
-    CompositorFrame frame = test::MakeCompositorFrame();
-    pass_list.swap(frame.render_pass_list);
-
-    support_->SubmitCompositorFrame(local_surface_id, std::move(frame));
-    EXPECT_TRUE(scheduler_->damaged);
-    EXPECT_FALSE(scheduler_->display_resized_);
-    EXPECT_FALSE(scheduler_->has_new_root_surface);
-
-    scheduler_->swapped = false;
-    display_->Resize(gfx::Size(100, 100));
-    EXPECT_TRUE(scheduler_->swapped);
-    EXPECT_EQ(5u, output_surface_->num_sent_frames());
-
-    // Latency info from previous frame should be sent now.
-    EXPECT_EQ(1u, output_surface_->last_sent_frame()->latency_info.size());
-  }
-
-  {
-    local_surface_id = id_allocator_.GenerateId();
-    display_->SetLocalSurfaceId(local_surface_id, 1.0f);
-    // Surface that's damaged completely should be resized and swapped.
-    pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 99, 99);
-    pass->damage_rect = gfx::Rect(0, 0, 99, 99);
-    pass->id = 1u;
-
-    pass_list.push_back(std::move(pass));
-    scheduler_->ResetDamageForTest();
-    SubmitCompositorFrame(&pass_list, local_surface_id);
-    EXPECT_TRUE(scheduler_->damaged);
-    EXPECT_FALSE(scheduler_->display_resized_);
-    EXPECT_FALSE(scheduler_->has_new_root_surface);
-
-    scheduler_->swapped = false;
-    display_->DrawAndSwap();
-    EXPECT_TRUE(scheduler_->swapped);
-    EXPECT_EQ(6u, output_surface_->num_sent_frames());
-    EXPECT_EQ(gfx::Size(100, 100),
-              software_output_device_->viewport_pixel_size());
-    EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
-              software_output_device_->damage_rect());
-    EXPECT_EQ(0u, output_surface_->last_sent_frame()->latency_info.size());
-  }
-  TearDownDisplay();
-}
-
-// Check LatencyInfo storage is cleaned up if it exceeds the limit.
-TEST_F(DisplayTest, MaxLatencyInfoCap) {
-  RendererSettings settings;
-  settings.partial_swap_enabled = true;
-  settings.finish_rendering_on_resize = true;
-  SetUpDisplay(settings, nullptr);
-  gfx::ColorSpace color_space_1 = gfx::ColorSpace::CreateXYZD50();
-  gfx::ColorSpace color_space_2 = gfx::ColorSpace::CreateSCRGBLinear();
-
-  StubDisplayClient client;
-  display_->Initialize(&client, manager_.surface_manager());
-  display_->SetColorSpace(color_space_1, color_space_1);
-
-  viz::LocalSurfaceId local_surface_id(id_allocator_.GenerateId());
-  display_->SetLocalSurfaceId(local_surface_id, 1.f);
-
-  scheduler_->ResetDamageForTest();
-  display_->Resize(gfx::Size(100, 100));
-
-  RenderPassList pass_list;
-  std::unique_ptr<RenderPass> pass = RenderPass::Create();
-  pass->output_rect = gfx::Rect(0, 0, 100, 100);
-  pass->damage_rect = gfx::Rect(10, 10, 1, 1);
-  pass->id = 1u;
-  pass_list.push_back(std::move(pass));
-
-  scheduler_->ResetDamageForTest();
-  SubmitCompositorFrame(&pass_list, local_surface_id);
-
-  display_->DrawAndSwap();
-
-  // This is the same as LatencyInfo::kMaxLatencyInfoNumber.
-  const size_t max_latency_info_count = 100;
-  for (size_t i = 0; i <= max_latency_info_count; ++i) {
-    pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 100, 100);
-    pass->damage_rect = gfx::Rect(10, 10, 0, 0);
-    pass->id = 1u;
-
-    pass_list.push_back(std::move(pass));
-    scheduler_->ResetDamageForTest();
-
-    CompositorFrame frame = test::MakeCompositorFrame();
-    pass_list.swap(frame.render_pass_list);
-    frame.metadata.latency_info.push_back(ui::LatencyInfo());
-
-    support_->SubmitCompositorFrame(local_surface_id, std::move(frame));
-
-    display_->DrawAndSwap();
-
-    if (i < max_latency_info_count)
-      EXPECT_EQ(i + 1, display_->stored_latency_info_size_for_testing());
-    else
-      EXPECT_EQ(0u, display_->stored_latency_info_size_for_testing());
-  }
-
-  TearDownDisplay();
-}
-
-class MockedContext : public TestWebGraphicsContext3D {
- public:
-  MOCK_METHOD0(shallowFinishCHROMIUM, void());
-};
-
-TEST_F(DisplayTest, Finish) {
-  viz::LocalSurfaceId local_surface_id1(id_allocator_.GenerateId());
-  viz::LocalSurfaceId local_surface_id2(id_allocator_.GenerateId());
-
-  RendererSettings settings;
-  settings.partial_swap_enabled = true;
-  settings.finish_rendering_on_resize = true;
-
-  std::unique_ptr<MockedContext> context(new MockedContext());
-  MockedContext* context_ptr = context.get();
-  EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM()).Times(0);
-
-  SetUpDisplay(settings, std::move(context));
-
-  StubDisplayClient client;
-  display_->Initialize(&client, manager_.surface_manager());
-
-  display_->SetLocalSurfaceId(local_surface_id1, 1.f);
-
-  display_->Resize(gfx::Size(100, 100));
-
-  {
-    RenderPassList pass_list;
-    std::unique_ptr<RenderPass> pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 100, 100);
-    pass->damage_rect = gfx::Rect(10, 10, 1, 1);
-    pass->id = 1u;
-    pass_list.push_back(std::move(pass));
-
-    SubmitCompositorFrame(&pass_list, local_surface_id1);
-  }
-
-  display_->DrawAndSwap();
-
-  // First resize and draw shouldn't finish.
-  testing::Mock::VerifyAndClearExpectations(context_ptr);
-
-  EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM());
-  display_->Resize(gfx::Size(150, 150));
-  testing::Mock::VerifyAndClearExpectations(context_ptr);
-
-  // Another resize without a swap doesn't need to finish.
-  EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM()).Times(0);
-  display_->SetLocalSurfaceId(local_surface_id2, 1.f);
-  display_->Resize(gfx::Size(200, 200));
-  testing::Mock::VerifyAndClearExpectations(context_ptr);
-
-  EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM()).Times(0);
-  {
-    RenderPassList pass_list;
-    std::unique_ptr<RenderPass> pass = RenderPass::Create();
-    pass->output_rect = gfx::Rect(0, 0, 200, 200);
-    pass->damage_rect = gfx::Rect(10, 10, 1, 1);
-    pass->id = 1u;
-    pass_list.push_back(std::move(pass));
-
-    SubmitCompositorFrame(&pass_list, local_surface_id2);
-  }
-
-  display_->DrawAndSwap();
-
-  testing::Mock::VerifyAndClearExpectations(context_ptr);
-
-  EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM());
-  display_->Resize(gfx::Size(250, 250));
-  testing::Mock::VerifyAndClearExpectations(context_ptr);
-  TearDownDisplay();
-}
-
-class CountLossDisplayClient : public StubDisplayClient {
- public:
-  CountLossDisplayClient() = default;
-
-  void DisplayOutputSurfaceLost() override { ++loss_count_; }
-
-  int loss_count() const { return loss_count_; }
-
- private:
-  int loss_count_ = 0;
-};
-
-TEST_F(DisplayTest, ContextLossInformsClient) {
-  SetUpDisplay(RendererSettings(), TestWebGraphicsContext3D::Create());
-
-  CountLossDisplayClient client;
-  display_->Initialize(&client, manager_.surface_manager());
-
-  // Verify DidLoseOutputSurface callback is hooked up correctly.
-  EXPECT_EQ(0, client.loss_count());
-  output_surface_->context_provider()->ContextGL()->LoseContextCHROMIUM(
-      GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
-  output_surface_->context_provider()->ContextGL()->Flush();
-  EXPECT_EQ(1, client.loss_count());
-  TearDownDisplay();
-}
-
-// Regression test for https://crbug.com/727162: Submitting a CompositorFrame to
-// a surface should only cause damage on the Display the surface belongs to.
-// There should not be a side-effect on other Displays.
-TEST_F(DisplayTest, CompositorFrameDamagesCorrectDisplay) {
-  RendererSettings settings;
-  viz::LocalSurfaceId local_surface_id(id_allocator_.GenerateId());
-
-  // Set up first display.
-  SetUpDisplay(settings, nullptr);
-  StubDisplayClient client;
-  display_->Initialize(&client, manager_.surface_manager());
-  display_->SetLocalSurfaceId(local_surface_id, 1.f);
-
-  // Set up second frame sink + display.
-  auto support2 = CompositorFrameSinkSupport::Create(
-      nullptr, &manager_, kAnotherFrameSinkId, true /* is_root */,
-      true /* handles_frame_sink_id_invalidation */,
-      true /* needs_sync_points */);
-  auto begin_frame_source2 = base::MakeUnique<StubBeginFrameSource>();
-  auto scheduler_for_display2 = base::MakeUnique<TestDisplayScheduler>(
-      begin_frame_source2.get(), task_runner_.get());
-  TestDisplayScheduler* scheduler2 = scheduler_for_display2.get();
-  auto display2 = CreateDisplay(
-      settings, kAnotherFrameSinkId, std::move(scheduler_for_display2),
-      FakeOutputSurface::CreateSoftware(
-          base::MakeUnique<TestSoftwareOutputDevice>()));
-  manager_.RegisterBeginFrameSource(begin_frame_source2.get(),
-                                    kAnotherFrameSinkId);
-  StubDisplayClient client2;
-  display2->Initialize(&client2, manager_.surface_manager());
-  display2->SetLocalSurfaceId(local_surface_id, 1.f);
-
-  display_->Resize(gfx::Size(100, 100));
-  display2->Resize(gfx::Size(100, 100));
-
-  scheduler_->ResetDamageForTest();
-  scheduler2->ResetDamageForTest();
-  EXPECT_FALSE(scheduler_->damaged);
-  EXPECT_FALSE(scheduler2->damaged);
-
-  // Submit a frame for display_ with full damage.
-  RenderPassList pass_list;
-  std::unique_ptr<RenderPass> pass = RenderPass::Create();
-  pass->output_rect = gfx::Rect(0, 0, 100, 100);
-  pass->damage_rect = gfx::Rect(10, 10, 1, 1);
-  pass->id = 1;
-  pass_list.push_back(std::move(pass));
-
-  SubmitCompositorFrame(&pass_list, local_surface_id);
-
-  // Should have damaged only display_ but not display2.
-  EXPECT_TRUE(scheduler_->damaged);
-  EXPECT_FALSE(scheduler2->damaged);
-  manager_.UnregisterBeginFrameSource(begin_frame_source2.get());
-  TearDownDisplay();
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/surfaces/frame_sink_manager.cc b/cc/surfaces/frame_sink_manager.cc
index dea0fdf..b101ecd 100644
--- a/cc/surfaces/frame_sink_manager.cc
+++ b/cc/surfaces/frame_sink_manager.cc
@@ -8,7 +8,6 @@
 #include <stdint.h>
 
 #include "base/logging.h"
-#include "cc/surfaces/display.h"
 #include "cc/surfaces/frame_sink_manager_client.h"
 #include "cc/surfaces/primary_begin_frame_source.h"
 
diff --git a/cc/surfaces/surface_aggregator.cc b/cc/surfaces/surface_aggregator.cc
deleted file mode 100644
index 0b551f96..0000000
--- a/cc/surfaces/surface_aggregator.cc
+++ /dev/null
@@ -1,946 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/surfaces/surface_aggregator.h"
-
-#include <stddef.h>
-
-#include <map>
-
-#include "base/bind.h"
-#include "base/containers/adapters.h"
-#include "base/logging.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/stl_util.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/base/math_util.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/quads/draw_quad.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/shared_quad_state.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/surface_draw_quad.h"
-#include "cc/quads/texture_draw_quad.h"
-#include "cc/resources/resource_provider.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_client.h"
-#include "cc/surfaces/surface_manager.h"
-#include "cc/trees/blocking_task_runner.h"
-
-namespace cc {
-namespace {
-
-// Maximum bucket size for the UMA stats.
-constexpr int kUmaStatMaxSurfaces = 30;
-
-const char kUmaValidSurface[] =
-    "Compositing.SurfaceAggregator.SurfaceDrawQuad.ValidSurface";
-const char kUmaMissingSurface[] =
-    "Compositing.SurfaceAggregator.SurfaceDrawQuad.MissingSurface";
-const char kUmaNoActiveFrame[] =
-    "Compositing.SurfaceAggregator.SurfaceDrawQuad.NoActiveFrame";
-
-void MoveMatchingRequests(
-    RenderPassId render_pass_id,
-    std::multimap<RenderPassId, std::unique_ptr<CopyOutputRequest>>*
-        copy_requests,
-    std::vector<std::unique_ptr<CopyOutputRequest>>* output_requests) {
-  auto request_range = copy_requests->equal_range(render_pass_id);
-  for (auto it = request_range.first; it != request_range.second; ++it) {
-    DCHECK(it->second);
-    output_requests->push_back(std::move(it->second));
-  }
-  copy_requests->erase(request_range.first, request_range.second);
-}
-
-// Returns true if the damage rect is valid.
-bool CalculateQuadSpaceDamageRect(
-    const gfx::Transform& quad_to_target_transform,
-    const gfx::Transform& target_to_root_transform,
-    const gfx::Rect& root_damage_rect,
-    gfx::Rect* quad_space_damage_rect) {
-  gfx::Transform quad_to_root_transform(target_to_root_transform,
-                                        quad_to_target_transform);
-  gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization);
-  bool inverse_valid = quad_to_root_transform.GetInverse(&inverse_transform);
-  if (!inverse_valid)
-    return false;
-
-  *quad_space_damage_rect = MathUtil::ProjectEnclosingClippedRect(
-      inverse_transform, root_damage_rect);
-  return true;
-}
-
-}  // namespace
-
-SurfaceAggregator::SurfaceAggregator(SurfaceManager* manager,
-                                     ResourceProvider* provider,
-                                     bool aggregate_only_damaged)
-    : manager_(manager),
-      provider_(provider),
-      next_render_pass_id_(1),
-      aggregate_only_damaged_(aggregate_only_damaged),
-      weak_factory_(this) {
-  DCHECK(manager_);
-}
-
-SurfaceAggregator::~SurfaceAggregator() {
-  // Notify client of all surfaces being removed.
-  contained_surfaces_.clear();
-  ProcessAddedAndRemovedSurfaces();
-}
-
-SurfaceAggregator::PrewalkResult::PrewalkResult() {}
-
-SurfaceAggregator::PrewalkResult::~PrewalkResult() {}
-
-// Create a clip rect for an aggregated quad from the original clip rect and
-// the clip rect from the surface it's on.
-SurfaceAggregator::ClipData SurfaceAggregator::CalculateClipRect(
-    const ClipData& surface_clip,
-    const ClipData& quad_clip,
-    const gfx::Transform& target_transform) {
-  ClipData out_clip;
-  if (surface_clip.is_clipped)
-    out_clip = surface_clip;
-
-  if (quad_clip.is_clipped) {
-    // TODO(jamesr): This only works if target_transform maps integer
-    // rects to integer rects.
-    gfx::Rect final_clip =
-        MathUtil::MapEnclosingClippedRect(target_transform, quad_clip.rect);
-    if (out_clip.is_clipped)
-      out_clip.rect.Intersect(final_clip);
-    else
-      out_clip.rect = final_clip;
-    out_clip.is_clipped = true;
-  }
-
-  return out_clip;
-}
-
-RenderPassId SurfaceAggregator::RemapPassId(RenderPassId surface_local_pass_id,
-                                            const viz::SurfaceId& surface_id) {
-  auto key = std::make_pair(surface_id, surface_local_pass_id);
-  auto it = render_pass_allocator_map_.find(key);
-  if (it != render_pass_allocator_map_.end()) {
-    it->second.in_use = true;
-    return it->second.id;
-  }
-
-  RenderPassInfo render_pass_info;
-  render_pass_info.id = next_render_pass_id_++;
-  render_pass_allocator_map_[key] = render_pass_info;
-  return render_pass_info.id;
-}
-
-int SurfaceAggregator::ChildIdForSurface(Surface* surface) {
-  auto it = surface_id_to_resource_child_id_.find(surface->surface_id());
-  if (it == surface_id_to_resource_child_id_.end()) {
-    int child_id = provider_->CreateChild(
-        base::Bind(&SurfaceAggregator::UnrefResources, surface->client()));
-    provider_->SetChildNeedsSyncTokens(child_id, surface->needs_sync_tokens());
-    surface_id_to_resource_child_id_[surface->surface_id()] = child_id;
-    return child_id;
-  } else {
-    return it->second;
-  }
-}
-
-gfx::Rect SurfaceAggregator::DamageRectForSurface(
-    const Surface* surface,
-    const RenderPass& source,
-    const gfx::Rect& full_rect) const {
-  auto it = previous_contained_surfaces_.find(surface->surface_id());
-  if (it != previous_contained_surfaces_.end()) {
-    int previous_index = it->second;
-    if (previous_index == surface->frame_index())
-      return gfx::Rect();
-  }
-  const viz::SurfaceId& previous_surface_id =
-      surface->previous_frame_surface_id();
-
-  if (surface->surface_id() != previous_surface_id) {
-    it = previous_contained_surfaces_.find(previous_surface_id);
-  }
-  if (it != previous_contained_surfaces_.end()) {
-    int previous_index = it->second;
-    if (previous_index == surface->frame_index() - 1)
-      return source.damage_rect;
-  }
-
-  return full_rect;
-}
-
-// static
-void SurfaceAggregator::UnrefResources(
-    base::WeakPtr<SurfaceClient> surface_client,
-    const std::vector<ReturnedResource>& resources,
-    BlockingTaskRunner* main_thread_task_runner) {
-  if (surface_client)
-    surface_client->UnrefResources(resources);
-}
-
-void SurfaceAggregator::HandleSurfaceQuad(
-    const SurfaceDrawQuad* surface_quad,
-    const gfx::Transform& target_transform,
-    const ClipData& clip_rect,
-    RenderPass* dest_pass,
-    bool ignore_undamaged,
-    gfx::Rect* damage_rect_in_quad_space,
-    bool* damage_rect_in_quad_space_valid) {
-  viz::SurfaceId surface_id = surface_quad->surface_id;
-  // If this surface's id is already in our referenced set then it creates
-  // a cycle in the graph and should be dropped.
-  if (referenced_surfaces_.count(surface_id))
-    return;
-  Surface* surface = manager_->GetSurfaceForId(surface_id);
-  if (!surface || !surface->HasActiveFrame()) {
-    if (surface_quad->fallback_quad) {
-      HandleSurfaceQuad(surface_quad->fallback_quad, target_transform,
-                        clip_rect, dest_pass, ignore_undamaged,
-                        damage_rect_in_quad_space,
-                        damage_rect_in_quad_space_valid);
-    } else if (!surface) {
-      ++uma_stats_.missing_surface;
-    } else {
-      ++uma_stats_.no_active_frame;
-    }
-    return;
-  }
-  ++uma_stats_.valid_surface;
-
-  if (ignore_undamaged) {
-    gfx::Transform quad_to_target_transform(
-        target_transform,
-        surface_quad->shared_quad_state->quad_to_target_transform);
-    *damage_rect_in_quad_space_valid = CalculateQuadSpaceDamageRect(
-        quad_to_target_transform, dest_pass->transform_to_root_target,
-        root_damage_rect_, damage_rect_in_quad_space);
-    if (*damage_rect_in_quad_space_valid &&
-        !damage_rect_in_quad_space->Intersects(surface_quad->visible_rect)) {
-      return;
-    }
-  }
-
-  const CompositorFrame& frame = surface->GetActiveFrame();
-
-  // A map keyed by RenderPass id.
-  Surface::CopyRequestsMap copy_requests;
-  surface->TakeCopyOutputRequests(&copy_requests);
-
-  const RenderPassList& render_pass_list = frame.render_pass_list;
-  if (!valid_surfaces_.count(surface->surface_id())) {
-    for (auto& request : copy_requests)
-      request.second->SendEmptyResult();
-    return;
-  }
-
-  referenced_surfaces_.insert(surface_id);
-  // TODO(vmpstr): provider check is a hack for unittests that don't set up a
-  // resource provider.
-  ResourceProvider::ResourceIdMap empty_map;
-  const ResourceProvider::ResourceIdMap& child_to_parent_map =
-      provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface))
-                : empty_map;
-  bool merge_pass =
-      surface_quad->shared_quad_state->opacity == 1.f && copy_requests.empty();
-
-  const RenderPassList& referenced_passes = render_pass_list;
-  size_t passes_to_copy =
-      merge_pass ? referenced_passes.size() - 1 : referenced_passes.size();
-  for (size_t j = 0; j < passes_to_copy; ++j) {
-    const RenderPass& source = *referenced_passes[j];
-
-    size_t sqs_size = source.shared_quad_state_list.size();
-    size_t dq_size = source.quad_list.size();
-    std::unique_ptr<RenderPass> copy_pass(
-        RenderPass::Create(sqs_size, dq_size));
-
-    RenderPassId remapped_pass_id = RemapPassId(source.id, surface_id);
-
-    copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect,
-                      source.transform_to_root_target, source.filters,
-                      source.background_filters, blending_color_space_,
-                      source.has_transparent_background);
-
-    MoveMatchingRequests(source.id, &copy_requests, &copy_pass->copy_requests);
-
-    // Contributing passes aggregated in to the pass list need to take the
-    // transform of the surface quad into account to update their transform to
-    // the root surface.
-    copy_pass->transform_to_root_target.ConcatTransform(
-        surface_quad->shared_quad_state->quad_to_target_transform);
-    copy_pass->transform_to_root_target.ConcatTransform(target_transform);
-    copy_pass->transform_to_root_target.ConcatTransform(
-        dest_pass->transform_to_root_target);
-
-    CopyQuadsToPass(source.quad_list, source.shared_quad_state_list,
-                    child_to_parent_map, gfx::Transform(), ClipData(),
-                    copy_pass.get(), surface_id);
-
-    if (!copy_request_passes_.count(remapped_pass_id) &&
-        !moved_pixel_passes_.count(remapped_pass_id)) {
-      gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization);
-      if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) {
-        gfx::Rect damage_rect_in_render_pass_space =
-            MathUtil::ProjectEnclosingClippedRect(inverse_transform,
-                                                  root_damage_rect_);
-        copy_pass->damage_rect.Intersect(damage_rect_in_render_pass_space);
-      }
-    }
-
-    dest_pass_list_->push_back(std::move(copy_pass));
-  }
-
-  gfx::Transform surface_transform =
-      surface_quad->shared_quad_state->quad_to_target_transform;
-  surface_transform.ConcatTransform(target_transform);
-
-  const RenderPass& last_pass = *render_pass_list.back();
-  if (merge_pass) {
-    // TODO(jamesr): Clean up last pass special casing.
-    const QuadList& quads = last_pass.quad_list;
-
-    // Intersect the transformed visible rect and the clip rect to create a
-    // smaller cliprect for the quad.
-    ClipData surface_quad_clip_rect(
-        true, MathUtil::MapEnclosingClippedRect(
-                  surface_quad->shared_quad_state->quad_to_target_transform,
-                  surface_quad->visible_rect));
-    if (surface_quad->shared_quad_state->is_clipped) {
-      surface_quad_clip_rect.rect.Intersect(
-          surface_quad->shared_quad_state->clip_rect);
-    }
-
-    ClipData quads_clip =
-        CalculateClipRect(clip_rect, surface_quad_clip_rect, target_transform);
-
-    CopyQuadsToPass(quads, last_pass.shared_quad_state_list,
-                    child_to_parent_map, surface_transform, quads_clip,
-                    dest_pass, surface_id);
-  } else {
-    RenderPassId remapped_pass_id = RemapPassId(last_pass.id, surface_id);
-
-    SharedQuadState* shared_quad_state =
-        CopySharedQuadState(surface_quad->shared_quad_state, target_transform,
-                            clip_rect, dest_pass);
-
-    RenderPassDrawQuad* quad =
-        dest_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-    quad->SetNew(shared_quad_state, surface_quad->rect,
-                 surface_quad->visible_rect, remapped_pass_id, 0, gfx::RectF(),
-                 gfx::Size(), gfx::Vector2dF(), gfx::PointF(),
-                 gfx::RectF(surface_quad->rect));
-  }
-
-  // Need to re-query since referenced_surfaces_ iterators are not stable.
-  referenced_surfaces_.erase(referenced_surfaces_.find(surface_id));
-}
-
-void SurfaceAggregator::AddColorConversionPass() {
-  if (dest_pass_list_->empty())
-    return;
-
-  RenderPass* root_render_pass = dest_pass_list_->back().get();
-  if (root_render_pass->color_space == output_color_space_)
-    return;
-
-  gfx::Rect output_rect = root_render_pass->output_rect;
-  CHECK(root_render_pass->transform_to_root_target == gfx::Transform());
-
-  if (!color_conversion_render_pass_id_)
-    color_conversion_render_pass_id_ = next_render_pass_id_++;
-
-  std::unique_ptr<RenderPass> color_conversion_pass(RenderPass::Create(1, 1));
-  color_conversion_pass->SetNew(color_conversion_render_pass_id_, output_rect,
-                                root_render_pass->damage_rect,
-                                root_render_pass->transform_to_root_target);
-  color_conversion_pass->color_space = output_color_space_;
-
-  SharedQuadState* shared_quad_state =
-      color_conversion_pass->CreateAndAppendSharedQuadState();
-  shared_quad_state->quad_layer_rect = output_rect;
-  shared_quad_state->visible_quad_layer_rect = output_rect;
-  shared_quad_state->opacity = 1.f;
-
-  RenderPassDrawQuad* quad =
-      color_conversion_pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-  quad->SetNew(shared_quad_state, output_rect, output_rect,
-               root_render_pass->id, 0, gfx::RectF(), gfx::Size(),
-               gfx::Vector2dF(), gfx::PointF(), gfx::RectF(output_rect));
-  dest_pass_list_->push_back(std::move(color_conversion_pass));
-}
-
-SharedQuadState* SurfaceAggregator::CopySharedQuadState(
-    const SharedQuadState* source_sqs,
-    const gfx::Transform& target_transform,
-    const ClipData& clip_rect,
-    RenderPass* dest_render_pass) {
-  SharedQuadState* copy_shared_quad_state =
-      dest_render_pass->CreateAndAppendSharedQuadState();
-  *copy_shared_quad_state = *source_sqs;
-  // target_transform contains any transformation that may exist
-  // between the context that these quads are being copied from (i.e. the
-  // surface's draw transform when aggregated from within a surface) to the
-  // target space of the pass. This will be identity except when copying the
-  // root draw pass from a surface into a pass when the surface draw quad's
-  // transform is not identity.
-  copy_shared_quad_state->quad_to_target_transform.ConcatTransform(
-      target_transform);
-
-  ClipData new_clip_rect = CalculateClipRect(
-      clip_rect, ClipData(source_sqs->is_clipped, source_sqs->clip_rect),
-      target_transform);
-  copy_shared_quad_state->is_clipped = new_clip_rect.is_clipped;
-  copy_shared_quad_state->clip_rect = new_clip_rect.rect;
-  return copy_shared_quad_state;
-}
-
-void SurfaceAggregator::CopyQuadsToPass(
-    const QuadList& source_quad_list,
-    const SharedQuadStateList& source_shared_quad_state_list,
-    const ResourceProvider::ResourceIdMap& child_to_parent_map,
-    const gfx::Transform& target_transform,
-    const ClipData& clip_rect,
-    RenderPass* dest_pass,
-    const viz::SurfaceId& surface_id) {
-  const SharedQuadState* last_copied_source_shared_quad_state = nullptr;
-  const SharedQuadState* dest_shared_quad_state = nullptr;
-  // If the current frame has copy requests then aggregate the entire
-  // thing, as otherwise parts of the copy requests may be ignored.
-  const bool ignore_undamaged = aggregate_only_damaged_ &&
-                                !has_copy_requests_ &&
-                                !moved_pixel_passes_.count(dest_pass->id);
-  // Damage rect in the quad space of the current shared quad state.
-  // TODO(jbauman): This rect may contain unnecessary area if
-  // transform isn't axis-aligned.
-  gfx::Rect damage_rect_in_quad_space;
-  bool damage_rect_in_quad_space_valid = false;
-
-#if DCHECK_IS_ON()
-  // If quads have come in with SharedQuadState out of order, or when quads have
-  // invalid SharedQuadState pointer, it should DCHECK.
-  SharedQuadStateList::ConstIterator sqs_iter =
-      source_shared_quad_state_list.begin();
-  for (auto* quad : source_quad_list) {
-    while (sqs_iter != source_shared_quad_state_list.end() &&
-           quad->shared_quad_state != *sqs_iter) {
-      ++sqs_iter;
-    }
-    DCHECK(sqs_iter != source_shared_quad_state_list.end());
-  }
-#endif
-
-  for (auto* quad : source_quad_list) {
-    if (quad->material == DrawQuad::SURFACE_CONTENT) {
-      const SurfaceDrawQuad* surface_quad = SurfaceDrawQuad::MaterialCast(quad);
-      // HandleSurfaceQuad may add other shared quad state, so reset the
-      // current data.
-      last_copied_source_shared_quad_state = nullptr;
-
-      // The primary SurfaceDrawQuad should have already dealt with the fallback
-      // DrawQuad.
-      if (surface_quad->surface_draw_quad_type == SurfaceDrawQuadType::FALLBACK)
-        continue;
-
-      HandleSurfaceQuad(surface_quad, target_transform, clip_rect, dest_pass,
-                        ignore_undamaged, &damage_rect_in_quad_space,
-                        &damage_rect_in_quad_space_valid);
-    } else {
-      if (quad->shared_quad_state != last_copied_source_shared_quad_state) {
-        dest_shared_quad_state = CopySharedQuadState(
-            quad->shared_quad_state, target_transform, clip_rect, dest_pass);
-        last_copied_source_shared_quad_state = quad->shared_quad_state;
-        if (aggregate_only_damaged_ && !has_copy_requests_) {
-          damage_rect_in_quad_space_valid = CalculateQuadSpaceDamageRect(
-              dest_shared_quad_state->quad_to_target_transform,
-              dest_pass->transform_to_root_target, root_damage_rect_,
-              &damage_rect_in_quad_space);
-        }
-      }
-
-      if (ignore_undamaged) {
-        if (damage_rect_in_quad_space_valid &&
-            !damage_rect_in_quad_space.Intersects(quad->visible_rect))
-          continue;
-      }
-
-      DrawQuad* dest_quad;
-      if (quad->material == DrawQuad::RENDER_PASS) {
-        const RenderPassDrawQuad* pass_quad =
-            RenderPassDrawQuad::MaterialCast(quad);
-        int original_pass_id = pass_quad->render_pass_id;
-        int remapped_pass_id = RemapPassId(original_pass_id, surface_id);
-
-        dest_quad = dest_pass->CopyFromAndAppendRenderPassDrawQuad(
-            pass_quad, dest_shared_quad_state, remapped_pass_id);
-      } else if (quad->material == DrawQuad::TEXTURE_CONTENT) {
-        const TextureDrawQuad* texture_quad =
-            TextureDrawQuad::MaterialCast(quad);
-        if (texture_quad->secure_output_only &&
-            (!output_is_secure_ || copy_request_passes_.count(dest_pass->id))) {
-          SolidColorDrawQuad* solid_color_quad =
-              dest_pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-          solid_color_quad->SetNew(dest_shared_quad_state, quad->rect,
-                                   quad->visible_rect, SK_ColorBLACK, false);
-          dest_quad = solid_color_quad;
-        } else {
-          dest_quad = dest_pass->CopyFromAndAppendDrawQuad(
-              quad, dest_shared_quad_state);
-        }
-      } else {
-        dest_quad =
-            dest_pass->CopyFromAndAppendDrawQuad(quad, dest_shared_quad_state);
-      }
-      if (!child_to_parent_map.empty()) {
-        for (ResourceId& resource_id : dest_quad->resources) {
-          ResourceProvider::ResourceIdMap::const_iterator it =
-              child_to_parent_map.find(resource_id);
-          DCHECK(it != child_to_parent_map.end());
-
-          DCHECK_EQ(it->first, resource_id);
-          ResourceId remapped_id = it->second;
-          resource_id = remapped_id;
-        }
-      }
-    }
-  }
-}
-
-void SurfaceAggregator::CopyPasses(const CompositorFrame& frame,
-                                   Surface* surface) {
-  // The root surface is allowed to have copy output requests, so grab them
-  // off its render passes. This map contains a set of CopyOutputRequests
-  // keyed by each RenderPass id.
-  Surface::CopyRequestsMap copy_requests;
-  surface->TakeCopyOutputRequests(&copy_requests);
-
-  const RenderPassList& source_pass_list = frame.render_pass_list;
-  DCHECK(valid_surfaces_.count(surface->surface_id()));
-  if (!valid_surfaces_.count(surface->surface_id()))
-    return;
-
-  // TODO(vmpstr): provider check is a hack for unittests that don't set up a
-  // resource provider.
-  ResourceProvider::ResourceIdMap empty_map;
-  const ResourceProvider::ResourceIdMap& child_to_parent_map =
-      provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface))
-                : empty_map;
-  for (size_t i = 0; i < source_pass_list.size(); ++i) {
-    const RenderPass& source = *source_pass_list[i];
-
-    size_t sqs_size = source.shared_quad_state_list.size();
-    size_t dq_size = source.quad_list.size();
-    std::unique_ptr<RenderPass> copy_pass(
-        RenderPass::Create(sqs_size, dq_size));
-
-    MoveMatchingRequests(source.id, &copy_requests, &copy_pass->copy_requests);
-
-    RenderPassId remapped_pass_id =
-        RemapPassId(source.id, surface->surface_id());
-
-    copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect,
-                      source.transform_to_root_target, source.filters,
-                      source.background_filters, blending_color_space_,
-                      source.has_transparent_background);
-
-    CopyQuadsToPass(source.quad_list, source.shared_quad_state_list,
-                    child_to_parent_map, gfx::Transform(), ClipData(),
-                    copy_pass.get(), surface->surface_id());
-    if (!copy_request_passes_.count(remapped_pass_id) &&
-        !moved_pixel_passes_.count(remapped_pass_id)) {
-      gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization);
-      if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) {
-        gfx::Rect damage_rect_in_render_pass_space =
-            MathUtil::ProjectEnclosingClippedRect(inverse_transform,
-                                                  root_damage_rect_);
-        copy_pass->damage_rect.Intersect(damage_rect_in_render_pass_space);
-      }
-    }
-
-    dest_pass_list_->push_back(std::move(copy_pass));
-  }
-}
-
-void SurfaceAggregator::ProcessAddedAndRemovedSurfaces() {
-  for (const auto& surface : previous_contained_surfaces_) {
-    if (!contained_surfaces_.count(surface.first)) {
-      // Release resources of removed surface.
-      auto it = surface_id_to_resource_child_id_.find(surface.first);
-      if (it != surface_id_to_resource_child_id_.end()) {
-        provider_->DestroyChild(it->second);
-        surface_id_to_resource_child_id_.erase(it);
-      }
-
-      // Notify client of removed surface.
-      Surface* surface_ptr = manager_->GetSurfaceForId(surface.first);
-      if (surface_ptr) {
-        surface_ptr->RunDrawCallback();
-      }
-    }
-  }
-}
-
-// Walk the Surface tree from surface_id. Validate the resources of the current
-// surface and its descendants, check if there are any copy requests, and
-// return the combined damage rect.
-gfx::Rect SurfaceAggregator::PrewalkTree(const viz::SurfaceId& surface_id,
-                                         bool in_moved_pixel_surface,
-                                         int parent_pass_id,
-                                         PrewalkResult* result) {
-  // This is for debugging a possible use after free.
-  // TODO(jbauman): Remove this once we have enough information.
-  // http://crbug.com/560181
-  base::WeakPtr<SurfaceAggregator> debug_weak_this = weak_factory_.GetWeakPtr();
-
-  if (referenced_surfaces_.count(surface_id))
-    return gfx::Rect();
-  Surface* surface = manager_->GetSurfaceForId(surface_id);
-  if (!surface) {
-    contained_surfaces_[surface_id] = 0;
-    return gfx::Rect();
-  }
-  contained_surfaces_[surface_id] = surface->frame_index();
-  if (!surface->HasActiveFrame())
-    return gfx::Rect();
-  const CompositorFrame& frame = surface->GetActiveFrame();
-  int child_id = 0;
-  // TODO(jbauman): hack for unit tests that don't set up rp
-  if (provider_) {
-    child_id = ChildIdForSurface(surface);
-    surface->RefResources(frame.resource_list);
-    provider_->ReceiveFromChild(child_id, frame.resource_list);
-  }
-  CHECK(debug_weak_this.get());
-
-  std::vector<ResourceId> referenced_resources;
-  size_t reserve_size = frame.resource_list.size();
-  referenced_resources.reserve(reserve_size);
-
-  bool invalid_frame = false;
-  ResourceProvider::ResourceIdMap empty_map;
-  const ResourceProvider::ResourceIdMap& child_to_parent_map =
-      provider_ ? provider_->GetChildToParentMap(child_id) : empty_map;
-
-  CHECK(debug_weak_this.get());
-  RenderPassId remapped_pass_id =
-      RemapPassId(frame.render_pass_list.back()->id, surface_id);
-  if (in_moved_pixel_surface)
-    moved_pixel_passes_.insert(remapped_pass_id);
-  if (parent_pass_id)
-    render_pass_dependencies_[parent_pass_id].insert(remapped_pass_id);
-
-  struct SurfaceInfo {
-    SurfaceInfo(const viz::SurfaceId& id,
-                bool has_moved_pixels,
-                RenderPassId parent_pass_id,
-                const gfx::Transform& target_to_surface_transform)
-        : id(id),
-          has_moved_pixels(has_moved_pixels),
-          parent_pass_id(parent_pass_id),
-          target_to_surface_transform(target_to_surface_transform) {}
-
-    viz::SurfaceId id;
-    bool has_moved_pixels;
-    RenderPassId parent_pass_id;
-    gfx::Transform target_to_surface_transform;
-  };
-  std::vector<SurfaceInfo> child_surfaces;
-
-  // This data is created once and typically small or empty. Collect all items
-  // and pass to a flat_vector to sort once.
-  std::vector<RenderPassId> pixel_moving_background_filter_passes_data;
-  for (const auto& render_pass : frame.render_pass_list) {
-    if (render_pass->background_filters.HasFilterThatMovesPixels()) {
-      pixel_moving_background_filter_passes_data.push_back(
-          RemapPassId(render_pass->id, surface_id));
-    }
-  }
-  base::flat_set<RenderPassId> pixel_moving_background_filter_passes(
-      std::move(pixel_moving_background_filter_passes_data),
-      base::KEEP_FIRST_OF_DUPES);
-
-  for (const auto& render_pass : base::Reversed(frame.render_pass_list)) {
-    RenderPassId remapped_pass_id = RemapPassId(render_pass->id, surface_id);
-    bool has_pixel_moving_filter =
-        render_pass->filters.HasFilterThatMovesPixels();
-    if (has_pixel_moving_filter)
-      moved_pixel_passes_.insert(remapped_pass_id);
-    bool in_moved_pixel_pass = has_pixel_moving_filter ||
-                               !!moved_pixel_passes_.count(remapped_pass_id);
-    for (auto* quad : render_pass->quad_list) {
-      if (quad->material == DrawQuad::SURFACE_CONTENT) {
-        const SurfaceDrawQuad* surface_quad =
-            SurfaceDrawQuad::MaterialCast(quad);
-        gfx::Transform target_to_surface_transform(
-            render_pass->transform_to_root_target,
-            surface_quad->shared_quad_state->quad_to_target_transform);
-        child_surfaces.emplace_back(surface_quad->surface_id,
-                                    in_moved_pixel_pass, remapped_pass_id,
-                                    target_to_surface_transform);
-      } else if (quad->material == DrawQuad::RENDER_PASS) {
-        const RenderPassDrawQuad* render_pass_quad =
-            RenderPassDrawQuad::MaterialCast(quad);
-        if (in_moved_pixel_pass) {
-          moved_pixel_passes_.insert(
-              RemapPassId(render_pass_quad->render_pass_id, surface_id));
-        }
-        if (pixel_moving_background_filter_passes.count(
-                render_pass_quad->render_pass_id)) {
-          in_moved_pixel_pass = true;
-        }
-        render_pass_dependencies_[remapped_pass_id].insert(
-            RemapPassId(render_pass_quad->render_pass_id, surface_id));
-      }
-
-      if (!provider_)
-        continue;
-      for (ResourceId resource_id : quad->resources) {
-        if (!child_to_parent_map.count(resource_id)) {
-          invalid_frame = true;
-          break;
-        }
-        referenced_resources.push_back(resource_id);
-      }
-    }
-  }
-
-  if (invalid_frame)
-    return gfx::Rect();
-  CHECK(debug_weak_this.get());
-  valid_surfaces_.insert(surface->surface_id());
-
-  ResourceIdSet resource_set(std::move(referenced_resources),
-                             base::KEEP_FIRST_OF_DUPES);
-  if (provider_)
-    provider_->DeclareUsedResourcesFromChild(child_id, resource_set);
-  CHECK(debug_weak_this.get());
-
-  gfx::Rect damage_rect;
-  gfx::Rect full_damage;
-  RenderPass* last_pass = frame.render_pass_list.back().get();
-  full_damage = last_pass->output_rect;
-  damage_rect =
-      DamageRectForSurface(surface, *last_pass, last_pass->output_rect);
-
-  // Avoid infinite recursion by adding current surface to
-  // referenced_surfaces_.
-  referenced_surfaces_.insert(surface->surface_id());
-  for (const auto& surface_info : child_surfaces) {
-    gfx::Rect surface_damage =
-        PrewalkTree(surface_info.id, surface_info.has_moved_pixels,
-                    surface_info.parent_pass_id, result);
-    if (surface_damage.IsEmpty())
-      continue;
-    if (surface_info.has_moved_pixels) {
-      // Areas outside the rect hit by target_to_surface_transform may be
-      // modified if there is a filter that moves pixels.
-      damage_rect = full_damage;
-      continue;
-    }
-
-    damage_rect.Union(MathUtil::MapEnclosingClippedRect(
-        surface_info.target_to_surface_transform, surface_damage));
-  }
-
-  CHECK(debug_weak_this.get());
-  for (const auto& surface_id : frame.metadata.referenced_surfaces) {
-    if (!contained_surfaces_.count(surface_id)) {
-      result->undrawn_surfaces.insert(surface_id);
-      PrewalkTree(surface_id, false, 0, result);
-    }
-  }
-
-  CHECK(debug_weak_this.get());
-  // TODO(staraz): It shouldn't need to call the callback when the damage is
-  // from |surface| and not from |child_surfaces|.
-  if (!damage_rect.IsEmpty()) {
-    surface->RunWillDrawCallback(damage_rect);
-    manager_->SurfaceWillDraw(surface->surface_id());
-  }
-
-  CHECK(debug_weak_this.get());
-  for (const auto& render_pass : frame.render_pass_list) {
-    if (!render_pass->copy_requests.empty()) {
-      RenderPassId remapped_pass_id = RemapPassId(render_pass->id, surface_id);
-      copy_request_passes_.insert(remapped_pass_id);
-    }
-  }
-
-  referenced_surfaces_.erase(referenced_surfaces_.find(surface->surface_id()));
-  if (!damage_rect.IsEmpty() && frame.metadata.may_contain_video)
-    result->may_contain_video = true;
-  return damage_rect;
-}
-
-void SurfaceAggregator::CopyUndrawnSurfaces(PrewalkResult* prewalk_result) {
-  // undrawn_surfaces are Surfaces that were identified by prewalk as being
-  // referenced by a drawn Surface, but aren't contained in a SurfaceDrawQuad.
-  // They need to be iterated over to ensure that any copy requests on them
-  // (or on Surfaces they reference) are executed.
-  std::vector<viz::SurfaceId> surfaces_to_copy(
-      prewalk_result->undrawn_surfaces.begin(),
-      prewalk_result->undrawn_surfaces.end());
-  DCHECK(referenced_surfaces_.empty());
-
-  for (size_t i = 0; i < surfaces_to_copy.size(); i++) {
-    viz::SurfaceId surface_id = surfaces_to_copy[i];
-    Surface* surface = manager_->GetSurfaceForId(surface_id);
-    if (!surface)
-      continue;
-    if (!surface->HasActiveFrame())
-      continue;
-    const CompositorFrame& frame = surface->GetActiveFrame();
-    bool surface_has_copy_requests = false;
-    for (const auto& render_pass : frame.render_pass_list) {
-      surface_has_copy_requests |= !render_pass->copy_requests.empty();
-    }
-    if (!surface_has_copy_requests) {
-      // Children are not necessarily included in undrawn_surfaces (because
-      // they weren't referenced directly from a drawn surface), but may have
-      // copy requests, so make sure to check them as well.
-      for (const auto& child_id : frame.metadata.referenced_surfaces) {
-        // Don't iterate over the child Surface if it was already listed as a
-        // child of a different Surface, or in the case where there's infinite
-        // recursion.
-        if (!prewalk_result->undrawn_surfaces.count(child_id)) {
-          surfaces_to_copy.push_back(child_id);
-          prewalk_result->undrawn_surfaces.insert(child_id);
-        }
-      }
-    } else {
-      referenced_surfaces_.insert(surface_id);
-      CopyPasses(frame, surface);
-      // CopyPasses may have mutated container, need to re-query to erase.
-      referenced_surfaces_.erase(referenced_surfaces_.find(surface_id));
-    }
-  }
-}
-
-void SurfaceAggregator::PropagateCopyRequestPasses() {
-  std::vector<RenderPassId> copy_requests_to_iterate(
-      copy_request_passes_.begin(), copy_request_passes_.end());
-  while (!copy_requests_to_iterate.empty()) {
-    int first = copy_requests_to_iterate.back();
-    copy_requests_to_iterate.pop_back();
-    auto it = render_pass_dependencies_.find(first);
-    if (it == render_pass_dependencies_.end())
-      continue;
-    for (auto pass : it->second) {
-      if (copy_request_passes_.insert(pass).second) {
-        copy_requests_to_iterate.push_back(pass);
-      }
-    }
-  }
-}
-
-CompositorFrame SurfaceAggregator::Aggregate(const viz::SurfaceId& surface_id) {
-  uma_stats_.Reset();
-
-  Surface* surface = manager_->GetSurfaceForId(surface_id);
-  DCHECK(surface);
-  contained_surfaces_[surface_id] = surface->frame_index();
-
-  if (!surface->HasActiveFrame())
-    return CompositorFrame();
-
-  const CompositorFrame& root_surface_frame = surface->GetActiveFrame();
-  TRACE_EVENT0("cc", "SurfaceAggregator::Aggregate");
-
-  CompositorFrame frame;
-
-  dest_pass_list_ = &frame.render_pass_list;
-
-  valid_surfaces_.clear();
-  PrewalkResult prewalk_result;
-  root_damage_rect_ = PrewalkTree(surface_id, false, 0, &prewalk_result);
-  PropagateCopyRequestPasses();
-  has_copy_requests_ = !copy_request_passes_.empty();
-  frame.metadata.may_contain_video = prewalk_result.may_contain_video;
-
-  CopyUndrawnSurfaces(&prewalk_result);
-  referenced_surfaces_.insert(surface_id);
-  CopyPasses(root_surface_frame, surface);
-  // CopyPasses may have mutated container, need to re-query to erase.
-  referenced_surfaces_.erase(referenced_surfaces_.find(surface_id));
-  AddColorConversionPass();
-
-  moved_pixel_passes_.clear();
-  copy_request_passes_.clear();
-  render_pass_dependencies_.clear();
-
-  // Remove all render pass mappings that weren't used in the current frame.
-  for (auto it = render_pass_allocator_map_.begin();
-       it != render_pass_allocator_map_.end();) {
-    if (it->second.in_use) {
-      it->second.in_use = false;
-      it++;
-    } else {
-      it = render_pass_allocator_map_.erase(it);
-    }
-  }
-
-  DCHECK(referenced_surfaces_.empty());
-
-  if (dest_pass_list_->empty())
-    return CompositorFrame();
-
-  dest_pass_list_ = NULL;
-  ProcessAddedAndRemovedSurfaces();
-  contained_surfaces_.swap(previous_contained_surfaces_);
-  contained_surfaces_.clear();
-
-  for (auto it : previous_contained_surfaces_) {
-    Surface* surface = manager_->GetSurfaceForId(it.first);
-    if (surface)
-      surface->TakeLatencyInfo(&frame.metadata.latency_info);
-  }
-
-  // TODO(jamesr): Aggregate all resource references into the returned frame's
-  // resource list.
-
-  // Log UMA stats for SurfaceDrawQuads on the number of surfaces that were
-  // aggregated together and any failures.
-  UMA_HISTOGRAM_EXACT_LINEAR(kUmaValidSurface, uma_stats_.valid_surface,
-                             kUmaStatMaxSurfaces);
-  UMA_HISTOGRAM_EXACT_LINEAR(kUmaMissingSurface, uma_stats_.missing_surface,
-                             kUmaStatMaxSurfaces);
-  UMA_HISTOGRAM_EXACT_LINEAR(kUmaNoActiveFrame, uma_stats_.no_active_frame,
-                             kUmaStatMaxSurfaces);
-
-  return frame;
-}
-
-void SurfaceAggregator::ReleaseResources(const viz::SurfaceId& surface_id) {
-  auto it = surface_id_to_resource_child_id_.find(surface_id);
-  if (it != surface_id_to_resource_child_id_.end()) {
-    provider_->DestroyChild(it->second);
-    surface_id_to_resource_child_id_.erase(it);
-  }
-}
-
-void SurfaceAggregator::SetFullDamageForSurface(
-    const viz::SurfaceId& surface_id) {
-  auto it = previous_contained_surfaces_.find(surface_id);
-  if (it == previous_contained_surfaces_.end())
-    return;
-  // Set the last drawn index as 0 to ensure full damage next time it's drawn.
-  it->second = 0;
-}
-
-void SurfaceAggregator::SetOutputColorSpace(
-    const gfx::ColorSpace& blending_color_space,
-    const gfx::ColorSpace& output_color_space) {
-  blending_color_space_ = blending_color_space.IsValid()
-                              ? blending_color_space
-                              : gfx::ColorSpace::CreateSRGB();
-  output_color_space_ = output_color_space.IsValid()
-                            ? output_color_space
-                            : gfx::ColorSpace::CreateSRGB();
-}
-
-}  // namespace cc
diff --git a/cc/surfaces/surface_aggregator.h b/cc/surfaces/surface_aggregator.h
deleted file mode 100644
index 773fbdc..0000000
--- a/cc/surfaces/surface_aggregator.h
+++ /dev/null
@@ -1,221 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_SURFACES_SURFACE_AGGREGATOR_H_
-#define CC_SURFACES_SURFACE_AGGREGATOR_H_
-
-#include <memory>
-#include <unordered_map>
-
-#include "base/containers/flat_map.h"
-#include "base/containers/flat_set.h"
-#include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "cc/quads/draw_quad.h"
-#include "cc/quads/render_pass.h"
-#include "cc/resources/transferable_resource.h"
-#include "cc/surfaces/surfaces_export.h"
-#include "components/viz/common/surface_id.h"
-#include "ui/gfx/color_space.h"
-
-namespace cc {
-
-class BlockingTaskRunner;
-class CompositorFrame;
-class ResourceProvider;
-class Surface;
-class SurfaceClient;
-class SurfaceDrawQuad;
-class SurfaceManager;
-
-class CC_SURFACES_EXPORT SurfaceAggregator {
- public:
-  using SurfaceIndexMap = base::flat_map<viz::SurfaceId, int>;
-
-  SurfaceAggregator(SurfaceManager* manager,
-                    ResourceProvider* provider,
-                    bool aggregate_only_damaged);
-  ~SurfaceAggregator();
-
-  CompositorFrame Aggregate(const viz::SurfaceId& surface_id);
-  void ReleaseResources(const viz::SurfaceId& surface_id);
-  SurfaceIndexMap& previous_contained_surfaces() {
-    return previous_contained_surfaces_;
-  }
-  void SetFullDamageForSurface(const viz::SurfaceId& surface_id);
-  void set_output_is_secure(bool secure) { output_is_secure_ = secure; }
-
-  // Set the color spaces for the created RenderPasses, which is propagated
-  // to the output surface.
-  void SetOutputColorSpace(const gfx::ColorSpace& blending_color_space,
-                           const gfx::ColorSpace& output_color_space);
-
- private:
-  struct ClipData {
-    ClipData() : is_clipped(false) {}
-    ClipData(bool is_clipped, const gfx::Rect& rect)
-        : is_clipped(is_clipped), rect(rect) {}
-
-    bool is_clipped;
-    gfx::Rect rect;
-  };
-
-  struct PrewalkResult {
-    PrewalkResult();
-    ~PrewalkResult();
-    // This is the set of Surfaces that were referenced by another Surface, but
-    // not included in a SurfaceDrawQuad.
-    base::flat_set<viz::SurfaceId> undrawn_surfaces;
-    bool may_contain_video = false;
-  };
-
-  struct RenderPassInfo {
-    // This is the id the pass is mapped to.
-    int id;
-    // This is true if the pass was used in the last aggregated frame.
-    bool in_use = true;
-  };
-
-  struct SurfaceDrawQuadUmaStats {
-    void Reset() {
-      valid_surface = 0;
-      missing_surface = 0;
-      no_active_frame = 0;
-    }
-
-    // The surface exists and has an active frame.
-    int valid_surface;
-    // The surface doesn't exist.
-    int missing_surface;
-    // The surface exists but doesn't have an active frame.
-    int no_active_frame;
-  };
-
-  ClipData CalculateClipRect(const ClipData& surface_clip,
-                             const ClipData& quad_clip,
-                             const gfx::Transform& target_transform);
-
-  RenderPassId RemapPassId(RenderPassId surface_local_pass_id,
-                           const viz::SurfaceId& surface_id);
-
-  void HandleSurfaceQuad(const SurfaceDrawQuad* surface_quad,
-                         const gfx::Transform& target_transform,
-                         const ClipData& clip_rect,
-                         RenderPass* dest_pass,
-                         bool ignore_undamaged,
-                         gfx::Rect* damage_rect_in_quad_space,
-                         bool* damage_rect_in_quad_space_valid);
-
-  SharedQuadState* CopySharedQuadState(const SharedQuadState* source_sqs,
-                                       const gfx::Transform& target_transform,
-                                       const ClipData& clip_rect,
-                                       RenderPass* dest_render_pass);
-  void CopyQuadsToPass(
-      const QuadList& source_quad_list,
-      const SharedQuadStateList& source_shared_quad_state_list,
-      const std::unordered_map<ResourceId, ResourceId>& resource_to_child_map,
-      const gfx::Transform& target_transform,
-      const ClipData& clip_rect,
-      RenderPass* dest_pass,
-      const viz::SurfaceId& surface_id);
-  gfx::Rect PrewalkTree(const viz::SurfaceId& surface_id,
-                        bool in_moved_pixel_surface,
-                        int parent_pass,
-                        PrewalkResult* result);
-  void CopyUndrawnSurfaces(PrewalkResult* prewalk);
-  void CopyPasses(const CompositorFrame& frame, Surface* surface);
-  void AddColorConversionPass();
-
-  // Remove Surfaces that were referenced before but aren't currently
-  // referenced from the ResourceProvider.
-  // Also notifies SurfaceAggregatorClient of newly added and removed
-  // child surfaces.
-  void ProcessAddedAndRemovedSurfaces();
-
-  void PropagateCopyRequestPasses();
-
-  int ChildIdForSurface(Surface* surface);
-  gfx::Rect DamageRectForSurface(const Surface* surface,
-                                 const RenderPass& source,
-                                 const gfx::Rect& full_rect) const;
-
-  static void UnrefResources(base::WeakPtr<SurfaceClient> surface_client,
-                             const std::vector<ReturnedResource>& resources,
-                             BlockingTaskRunner* main_thread_task_runner);
-
-  SurfaceManager* manager_;
-  ResourceProvider* provider_;
-
-  // Every Surface has its own RenderPass ID namespace. This structure maps
-  // each source (viz::SurfaceId, RenderPass id) to a unified ID namespace
-  // that's used in the aggregated frame. An entry is removed from the map if
-  // it's not used for one output frame.
-  base::flat_map<std::pair<viz::SurfaceId, RenderPassId>, RenderPassInfo>
-      render_pass_allocator_map_;
-  RenderPassId next_render_pass_id_;
-  const bool aggregate_only_damaged_;
-  bool output_is_secure_;
-
-  // The color space for the root render pass. If this is different from
-  // |blending_color_space_|, then a final render pass to convert between
-  // the two will be added. This space must always be valid.
-  gfx::ColorSpace output_color_space_ = gfx::ColorSpace::CreateSRGB();
-  // The color space in which blending is done, used for all non-root render
-  // passes. This space must always be valid.
-  gfx::ColorSpace blending_color_space_ = gfx::ColorSpace::CreateSRGB();
-  // The id for the final color conversion render pass.
-  RenderPassId color_conversion_render_pass_id_ = 0;
-
-  base::flat_map<viz::SurfaceId, int> surface_id_to_resource_child_id_;
-
-  // The following state is only valid for the duration of one Aggregate call
-  // and is only stored on the class to avoid having to pass through every
-  // function call.
-
-  // This is the set of surfaces referenced in the aggregation so far, used to
-  // detect cycles.
-  base::flat_set<viz::SurfaceId> referenced_surfaces_;
-
-  // For each Surface used in the last aggregation, gives the frame_index at
-  // that time.
-  SurfaceIndexMap previous_contained_surfaces_;
-  SurfaceIndexMap contained_surfaces_;
-
-  // After surface validation, every Surface in this set is valid.
-  base::flat_set<viz::SurfaceId> valid_surfaces_;
-
-  // This is the pass list for the aggregated frame.
-  RenderPassList* dest_pass_list_;
-
-  // This is the set of aggregated pass ids that are affected by filters that
-  // move pixels.
-  base::flat_set<RenderPassId> moved_pixel_passes_;
-
-  // This is the set of aggregated pass ids that are drawn by copy requests, so
-  // should not have their damage rects clipped to the root damage rect.
-  base::flat_set<RenderPassId> copy_request_passes_;
-
-  // This maps each aggregated pass id to the set of (aggregated) pass ids
-  // that its RenderPassDrawQuads depend on
-  base::flat_map<RenderPassId, base::flat_set<RenderPassId>>
-      render_pass_dependencies_;
-
-  // The root damage rect of the currently-aggregating frame.
-  gfx::Rect root_damage_rect_;
-
-  // True if the frame that's currently being aggregated has copy requests.
-  // This is valid during Aggregate after PrewalkTree is called.
-  bool has_copy_requests_;
-
-  // Tracks UMA stats for SurfaceDrawQuads during a call to Aggregate().
-  SurfaceDrawQuadUmaStats uma_stats_;
-
-  base::WeakPtrFactory<SurfaceAggregator> weak_factory_;
-
-  DISALLOW_COPY_AND_ASSIGN(SurfaceAggregator);
-};
-
-}  // namespace cc
-
-#endif  // CC_SURFACES_SURFACE_AGGREGATOR_H_
diff --git a/cc/surfaces/surface_aggregator_perftest.cc b/cc/surfaces/surface_aggregator_perftest.cc
deleted file mode 100644
index 0da1d6f6..0000000
--- a/cc/surfaces/surface_aggregator_perftest.cc
+++ /dev/null
@@ -1,192 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/memory/ptr_util.h"
-#include "cc/base/lap_timer.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/quads/surface_draw_quad.h"
-#include "cc/quads/texture_draw_quad.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
-#include "cc/surfaces/frame_sink_manager.h"
-#include "cc/surfaces/surface_aggregator.h"
-#include "cc/surfaces/surface_manager.h"
-#include "cc/test/compositor_frame_helpers.h"
-#include "cc/test/fake_output_surface_client.h"
-#include "cc/test/fake_resource_provider.h"
-#include "cc/test/test_context_provider.h"
-#include "cc/test/test_shared_bitmap_manager.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/perf/perf_test.h"
-
-namespace cc {
-namespace {
-
-constexpr bool kIsRoot = true;
-constexpr bool kIsChildRoot = false;
-constexpr bool kHandlesFrameSinkIdInvalidation = true;
-constexpr bool kNeedsSyncPoints = true;
-
-const base::UnguessableToken kArbitraryToken = base::UnguessableToken::Create();
-
-class SurfaceAggregatorPerfTest : public testing::Test {
- public:
-  SurfaceAggregatorPerfTest() {
-    context_provider_ = TestContextProvider::Create();
-    context_provider_->BindToCurrentThread();
-    shared_bitmap_manager_.reset(new TestSharedBitmapManager);
-
-    resource_provider_ = FakeResourceProvider::Create(
-        context_provider_.get(), shared_bitmap_manager_.get());
-  }
-
-  void RunTest(int num_surfaces,
-               int num_textures,
-               float opacity,
-               bool optimize_damage,
-               bool full_damage,
-               const std::string& name) {
-    std::vector<std::unique_ptr<CompositorFrameSinkSupport>> child_supports(
-        num_surfaces);
-    for (int i = 0; i < num_surfaces; i++) {
-      child_supports[i] = CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, viz::FrameSinkId(1, i + 1), kIsChildRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-    }
-    aggregator_.reset(new SurfaceAggregator(
-        manager_.surface_manager(), resource_provider_.get(), optimize_damage));
-    for (int i = 0; i < num_surfaces; i++) {
-      viz::LocalSurfaceId local_surface_id(i + 1, kArbitraryToken);
-
-      std::unique_ptr<RenderPass> pass(RenderPass::Create());
-      pass->output_rect = gfx::Rect(0, 0, 1, 2);
-
-      CompositorFrame frame = test::MakeEmptyCompositorFrame();
-
-      SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
-      for (int j = 0; j < num_textures; j++) {
-        TransferableResource resource;
-        resource.id = j;
-        resource.is_software = true;
-        frame.resource_list.push_back(resource);
-
-        TextureDrawQuad* quad =
-            pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-        const gfx::Rect rect(0, 0, 1, 2);
-        const gfx::Rect opaque_rect;
-        // Half of rects should be visible with partial damage.
-        gfx::Rect visible_rect =
-            j % 2 == 0 ? gfx::Rect(0, 0, 1, 2) : gfx::Rect(0, 1, 1, 1);
-        bool needs_blending = false;
-        bool premultiplied_alpha = false;
-        const gfx::PointF uv_top_left;
-        const gfx::PointF uv_bottom_right;
-        SkColor background_color = SK_ColorGREEN;
-        const float vertex_opacity[4] = {0.f, 0.f, 1.f, 1.f};
-        bool flipped = false;
-        bool nearest_neighbor = false;
-        quad->SetAll(sqs, rect, opaque_rect, visible_rect, needs_blending, j,
-                     gfx::Size(), premultiplied_alpha, uv_top_left,
-                     uv_bottom_right, background_color, vertex_opacity, flipped,
-                     nearest_neighbor, false);
-      }
-      sqs = pass->CreateAndAppendSharedQuadState();
-      sqs->opacity = opacity;
-      if (i >= 1) {
-        SurfaceDrawQuad* surface_quad =
-            pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-        surface_quad->SetNew(
-            sqs, gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1),
-            viz::SurfaceId(viz::FrameSinkId(1, i),
-                           viz::LocalSurfaceId(i, kArbitraryToken)),
-            SurfaceDrawQuadType::PRIMARY, nullptr);
-      }
-
-      frame.render_pass_list.push_back(std::move(pass));
-      child_supports[i]->SubmitCompositorFrame(local_surface_id,
-                                               std::move(frame));
-    }
-
-    std::unique_ptr<CompositorFrameSinkSupport> root_support =
-        CompositorFrameSinkSupport::Create(
-            nullptr, &manager_, viz::FrameSinkId(1, num_surfaces + 1), kIsRoot,
-            kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-    timer_.Reset();
-    do {
-      std::unique_ptr<RenderPass> pass(RenderPass::Create());
-      CompositorFrame frame = test::MakeEmptyCompositorFrame();
-
-      SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
-      SurfaceDrawQuad* surface_quad =
-          pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-      surface_quad->SetNew(
-          sqs, gfx::Rect(0, 0, 100, 100), gfx::Rect(0, 0, 100, 100),
-          viz::SurfaceId(viz::FrameSinkId(1, num_surfaces),
-                         viz::LocalSurfaceId(num_surfaces, kArbitraryToken)),
-          SurfaceDrawQuadType::PRIMARY, nullptr);
-
-      pass->output_rect = gfx::Rect(0, 0, 100, 100);
-
-      if (full_damage)
-        pass->damage_rect = gfx::Rect(0, 0, 100, 100);
-      else
-        pass->damage_rect = gfx::Rect(0, 0, 1, 1);
-
-      frame.render_pass_list.push_back(std::move(pass));
-
-      root_support->SubmitCompositorFrame(
-          viz::LocalSurfaceId(num_surfaces + 1, kArbitraryToken),
-          std::move(frame));
-
-      CompositorFrame aggregated = aggregator_->Aggregate(viz::SurfaceId(
-          viz::FrameSinkId(1, num_surfaces + 1),
-          viz::LocalSurfaceId(num_surfaces + 1, kArbitraryToken)));
-      timer_.NextLap();
-    } while (!timer_.HasTimeLimitExpired());
-
-    perf_test::PrintResult("aggregator_speed", "", name, timer_.LapsPerSecond(),
-                           "runs/s", true);
-    for (int i = 0; i < num_surfaces; i++)
-      child_supports[i]->EvictCurrentSurface();
-    root_support->EvictCurrentSurface();
-  }
-
- protected:
-  FrameSinkManager manager_;
-  scoped_refptr<TestContextProvider> context_provider_;
-  std::unique_ptr<viz::SharedBitmapManager> shared_bitmap_manager_;
-  std::unique_ptr<ResourceProvider> resource_provider_;
-  std::unique_ptr<SurfaceAggregator> aggregator_;
-  LapTimer timer_;
-};
-
-TEST_F(SurfaceAggregatorPerfTest, ManySurfacesOpaque) {
-  RunTest(20, 100, 1.f, false, true, "many_surfaces_opaque");
-}
-
-TEST_F(SurfaceAggregatorPerfTest, ManySurfacesTransparent) {
-  RunTest(20, 100, .5f, false, true, "many_surfaces_transparent");
-}
-
-TEST_F(SurfaceAggregatorPerfTest, FewSurfaces) {
-  RunTest(3, 1000, 1.f, false, true, "few_surfaces");
-}
-
-TEST_F(SurfaceAggregatorPerfTest, ManySurfacesOpaqueDamageCalc) {
-  RunTest(20, 100, 1.f, true, true, "many_surfaces_opaque_damage_calc");
-}
-
-TEST_F(SurfaceAggregatorPerfTest, ManySurfacesTransparentDamageCalc) {
-  RunTest(20, 100, .5f, true, true, "many_surfaces_transparent_damage_calc");
-}
-
-TEST_F(SurfaceAggregatorPerfTest, FewSurfacesDamageCalc) {
-  RunTest(3, 1000, 1.f, true, true, "few_surfaces_damage_calc");
-}
-
-TEST_F(SurfaceAggregatorPerfTest, FewSurfacesAggregateDamaged) {
-  RunTest(3, 1000, 1.f, true, false, "few_surfaces_aggregate_damaged");
-}
-
-}  // namespace
-}  // namespace cc
diff --git a/cc/surfaces/surface_aggregator_unittest.cc b/cc/surfaces/surface_aggregator_unittest.cc
deleted file mode 100644
index 36c5744..0000000
--- a/cc/surfaces/surface_aggregator_unittest.cc
+++ /dev/null
@@ -1,2364 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/surfaces/surface_aggregator.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include <utility>
-
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/quads/render_pass.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/surface_draw_quad.h"
-#include "cc/quads/texture_draw_quad.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
-#include "cc/surfaces/frame_sink_manager.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_manager.h"
-#include "cc/test/compositor_frame_helpers.h"
-#include "cc/test/fake_compositor_frame_sink_support_client.h"
-#include "cc/test/fake_resource_provider.h"
-#include "cc/test/fake_surface_observer.h"
-#include "cc/test/render_pass_test_utils.h"
-#include "cc/test/surface_aggregator_test_helpers.h"
-#include "cc/test/test_shared_bitmap_manager.h"
-#include "components/viz/common/local_surface_id_allocator.h"
-#include "components/viz/common/resources/shared_bitmap_manager.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkColor.h"
-
-namespace cc {
-namespace {
-
-constexpr viz::FrameSinkId kArbitraryRootFrameSinkId(1, 1);
-constexpr viz::FrameSinkId kArbitraryFrameSinkId1(2, 2);
-constexpr viz::FrameSinkId kArbitraryFrameSinkId2(3, 3);
-constexpr viz::FrameSinkId kArbitraryMiddleFrameSinkId(4, 4);
-constexpr viz::FrameSinkId kArbitraryReservedFrameSinkId(5, 5);
-constexpr viz::FrameSinkId kArbitraryFrameSinkId3(6, 6);
-const base::UnguessableToken kArbitraryToken = base::UnguessableToken::Create();
-constexpr bool kRootIsRoot = true;
-constexpr bool kChildIsRoot = false;
-constexpr bool kHandlesFrameSinkIdInvalidation = true;
-constexpr bool kNeedsSyncPoints = false;
-
-viz::SurfaceId InvalidSurfaceId() {
-  static viz::SurfaceId invalid(
-      viz::FrameSinkId(), viz::LocalSurfaceId(0xdeadbeef, kArbitraryToken));
-  return invalid;
-}
-
-gfx::Size SurfaceSize() {
-  static gfx::Size size(100, 100);
-  return size;
-}
-
-class SurfaceAggregatorTest : public testing::Test {
- public:
-  explicit SurfaceAggregatorTest(bool use_damage_rect)
-      : observer_(false),
-        support_(
-            CompositorFrameSinkSupport::Create(&fake_client_,
-                                               &manager_,
-                                               kArbitraryRootFrameSinkId,
-                                               kRootIsRoot,
-                                               kHandlesFrameSinkIdInvalidation,
-                                               kNeedsSyncPoints)),
-        aggregator_(manager_.surface_manager(), NULL, use_damage_rect) {
-    manager_.surface_manager()->AddObserver(&observer_);
-  }
-
-  SurfaceAggregatorTest() : SurfaceAggregatorTest(false) {}
-
-  void TearDown() override {
-    observer_.Reset();
-    support_->EvictCurrentSurface();
-    testing::Test::TearDown();
-  }
-
- protected:
-  FrameSinkManager manager_;
-  FakeSurfaceObserver observer_;
-  FakeCompositorFrameSinkSupportClient fake_client_;
-  std::unique_ptr<CompositorFrameSinkSupport> support_;
-  SurfaceAggregator aggregator_;
-};
-
-class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest {
- public:
-  explicit SurfaceAggregatorValidSurfaceTest(bool use_damage_rect)
-      : SurfaceAggregatorTest(use_damage_rect),
-        child_support_(
-            CompositorFrameSinkSupport::Create(nullptr,
-                                               &manager_,
-                                               kArbitraryReservedFrameSinkId,
-                                               kChildIsRoot,
-                                               kHandlesFrameSinkIdInvalidation,
-                                               kNeedsSyncPoints)) {}
-  SurfaceAggregatorValidSurfaceTest()
-      : SurfaceAggregatorValidSurfaceTest(false) {}
-
-  void SetUp() override {
-    SurfaceAggregatorTest::SetUp();
-    root_local_surface_id_ = allocator_.GenerateId();
-    root_surface_ = manager_.surface_manager()->GetSurfaceForId(
-        viz::SurfaceId(support_->frame_sink_id(), root_local_surface_id_));
-  }
-
-  void TearDown() override {
-    child_support_->EvictCurrentSurface();
-    SurfaceAggregatorTest::TearDown();
-  }
-
-  void AggregateAndVerify(test::Pass* expected_passes,
-                          size_t expected_pass_count,
-                          viz::SurfaceId* surface_ids,
-                          size_t expected_surface_count) {
-    CompositorFrame aggregated_frame = aggregator_.Aggregate(
-        viz::SurfaceId(support_->frame_sink_id(), root_local_surface_id_));
-
-    TestPassesMatchExpectations(expected_passes, expected_pass_count,
-                                &aggregated_frame.render_pass_list);
-
-    // Ensure no duplicate pass ids output.
-    std::set<RenderPassId> used_passes;
-    for (const auto& pass : aggregated_frame.render_pass_list) {
-      EXPECT_TRUE(used_passes.insert(pass->id).second);
-    }
-
-    EXPECT_EQ(expected_surface_count,
-              aggregator_.previous_contained_surfaces().size());
-    for (size_t i = 0; i < expected_surface_count; i++) {
-      EXPECT_TRUE(
-          aggregator_.previous_contained_surfaces().find(surface_ids[i]) !=
-          aggregator_.previous_contained_surfaces().end());
-    }
-  }
-
-  void SubmitPassListAsFrame(CompositorFrameSinkSupport* support,
-                             const viz::LocalSurfaceId& local_surface_id,
-                             RenderPassList* pass_list) {
-    CompositorFrame frame = test::MakeEmptyCompositorFrame();
-    pass_list->swap(frame.render_pass_list);
-
-    support->SubmitCompositorFrame(local_surface_id, std::move(frame));
-  }
-
-  void SubmitCompositorFrame(CompositorFrameSinkSupport* support,
-                             test::Pass* passes,
-                             size_t pass_count,
-                             const viz::LocalSurfaceId& local_surface_id) {
-    RenderPassList pass_list;
-    AddPasses(&pass_list, gfx::Rect(SurfaceSize()), passes, pass_count);
-    SubmitPassListAsFrame(support, local_surface_id, &pass_list);
-  }
-
-  void QueuePassAsFrame(std::unique_ptr<RenderPass> pass,
-                        const viz::LocalSurfaceId& local_surface_id,
-                        CompositorFrameSinkSupport* support) {
-    CompositorFrame child_frame = test::MakeEmptyCompositorFrame();
-    child_frame.render_pass_list.push_back(std::move(pass));
-
-    support->SubmitCompositorFrame(local_surface_id, std::move(child_frame));
-  }
-
- protected:
-  viz::LocalSurfaceId root_local_surface_id_;
-  Surface* root_surface_;
-  viz::LocalSurfaceIdAllocator allocator_;
-  std::unique_ptr<CompositorFrameSinkSupport> child_support_;
-  viz::LocalSurfaceIdAllocator child_allocator_;
-};
-
-// Tests that a very simple frame containing only two solid color quads makes it
-// through the aggregator correctly.
-TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleFrame) {
-  test::Quad quads[] = {test::Quad::SolidColorQuad(SK_ColorRED),
-                        test::Quad::SolidColorQuad(SK_ColorBLUE)};
-  test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
-
-  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
-                        root_local_surface_id_);
-
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  viz::SurfaceId ids[] = {root_surface_id};
-
-  AggregateAndVerify(passes, arraysize(passes), ids, arraysize(ids));
-
-  // Check that WillDrawSurface was called.
-  EXPECT_EQ(gfx::Rect(SurfaceSize()), fake_client_.last_damage_rect());
-  EXPECT_EQ(root_local_surface_id_, fake_client_.last_local_surface_id());
-
-  // Check that SurfaceObserver::OnSurfaceWillDraw was called.
-  EXPECT_TRUE(observer_.SurfaceWillDrawCalled(root_surface_id));
-}
-
-TEST_F(SurfaceAggregatorValidSurfaceTest, OpacityCopied) {
-  std::unique_ptr<CompositorFrameSinkSupport> embedded_support(
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryFrameSinkId1, kRootIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints));
-  viz::LocalSurfaceId embedded_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
-                                     embedded_local_surface_id);
-
-  test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
-                                 test::Quad::SolidColorQuad(SK_ColorBLUE)};
-  test::Pass embedded_passes[] = {
-      test::Pass(embedded_quads, arraysize(embedded_quads))};
-
-  SubmitCompositorFrame(embedded_support.get(), embedded_passes,
-                        arraysize(embedded_passes), embedded_local_surface_id);
-
-  test::Quad quads[] = {
-      test::Quad::SurfaceQuad(embedded_surface_id, InvalidSurfaceId(), .5f)};
-  test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
-
-  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
-                        root_local_surface_id_);
-
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-  RenderPassList& render_pass_list(aggregated_frame.render_pass_list);
-  ASSERT_EQ(2u, render_pass_list.size());
-  SharedQuadStateList& shared_quad_state_list(
-      render_pass_list[0]->shared_quad_state_list);
-  ASSERT_EQ(2u, shared_quad_state_list.size());
-  EXPECT_EQ(1.f, shared_quad_state_list.ElementAt(0)->opacity);
-  EXPECT_EQ(1.f, shared_quad_state_list.ElementAt(1)->opacity);
-
-  SharedQuadStateList& shared_quad_state_list2(
-      render_pass_list[1]->shared_quad_state_list);
-  ASSERT_EQ(1u, shared_quad_state_list2.size());
-  EXPECT_EQ(.5f, shared_quad_state_list2.ElementAt(0)->opacity);
-
-  embedded_support->EvictCurrentSurface();
-}
-
-TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSimpleFrame) {
-  test::Quad quads[][2] = {{test::Quad::SolidColorQuad(SK_ColorWHITE),
-                            test::Quad::SolidColorQuad(SK_ColorLTGRAY)},
-                           {test::Quad::SolidColorQuad(SK_ColorGRAY),
-                            test::Quad::SolidColorQuad(SK_ColorDKGRAY)}};
-  test::Pass passes[] = {test::Pass(quads[0], arraysize(quads[0]), 1),
-                         test::Pass(quads[1], arraysize(quads[1]), 2)};
-
-  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
-                        root_local_surface_id_);
-
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  viz::SurfaceId ids[] = {root_surface_id};
-
-  AggregateAndVerify(passes, arraysize(passes), ids, arraysize(ids));
-}
-
-// Ensure that the render pass ID map properly keeps and deletes entries.
-TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassDeallocation) {
-  test::Quad quads[][2] = {{test::Quad::SolidColorQuad(SK_ColorWHITE),
-                            test::Quad::SolidColorQuad(SK_ColorLTGRAY)},
-                           {test::Quad::SolidColorQuad(SK_ColorGRAY),
-                            test::Quad::SolidColorQuad(SK_ColorDKGRAY)}};
-  test::Pass passes[] = {test::Pass(quads[0], arraysize(quads[0]), 2),
-                         test::Pass(quads[1], arraysize(quads[1]), 1)};
-
-  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
-                        root_local_surface_id_);
-
-  viz::SurfaceId surface_id(support_->frame_sink_id(), root_local_surface_id_);
-
-  CompositorFrame aggregated_frame;
-  aggregated_frame = aggregator_.Aggregate(surface_id);
-  auto id0 = aggregated_frame.render_pass_list[0]->id;
-  auto id1 = aggregated_frame.render_pass_list[1]->id;
-  EXPECT_NE(id1, id0);
-
-  // Aggregated RenderPass ids should remain the same between frames.
-  aggregated_frame = aggregator_.Aggregate(surface_id);
-  EXPECT_EQ(id0, aggregated_frame.render_pass_list[0]->id);
-  EXPECT_EQ(id1, aggregated_frame.render_pass_list[1]->id);
-
-  test::Pass passes2[] = {test::Pass(quads[0], arraysize(quads[0]), 3),
-                          test::Pass(quads[1], arraysize(quads[1]), 1)};
-
-  SubmitCompositorFrame(support_.get(), passes2, arraysize(passes2),
-                        root_local_surface_id_);
-
-  // The RenderPass that still exists should keep the same ID.
-  aggregated_frame = aggregator_.Aggregate(surface_id);
-  auto id2 = aggregated_frame.render_pass_list[0]->id;
-  EXPECT_NE(id2, id1);
-  EXPECT_NE(id2, id0);
-  EXPECT_EQ(id1, aggregated_frame.render_pass_list[1]->id);
-
-  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
-                        root_local_surface_id_);
-
-  // |id1| didn't exist in the previous frame, so it should be
-  // mapped to a new ID.
-  aggregated_frame = aggregator_.Aggregate(surface_id);
-  auto id3 = aggregated_frame.render_pass_list[0]->id;
-  EXPECT_NE(id3, id2);
-  EXPECT_NE(id3, id1);
-  EXPECT_NE(id3, id0);
-  EXPECT_EQ(id1, aggregated_frame.render_pass_list[1]->id);
-}
-
-// This tests very simple embedding. root_surface has a frame containing a few
-// solid color quads and a surface quad referencing embedded_surface.
-// embedded_surface has a frame containing only a solid color quad. The solid
-// color quad should be aggregated into the final frame.
-TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleSurfaceReference) {
-  std::unique_ptr<CompositorFrameSinkSupport> embedded_support(
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryFrameSinkId1, kRootIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints));
-  viz::LocalSurfaceId embedded_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
-                                     embedded_local_surface_id);
-
-  test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)};
-  test::Pass embedded_passes[] = {
-      test::Pass(embedded_quads, arraysize(embedded_quads))};
-
-  SubmitCompositorFrame(embedded_support.get(), embedded_passes,
-                        arraysize(embedded_passes), embedded_local_surface_id);
-
-  test::Quad root_quads[] = {
-      test::Quad::SolidColorQuad(SK_ColorWHITE),
-      test::Quad::SurfaceQuad(embedded_surface_id, InvalidSurfaceId(), 1.f),
-      test::Quad::SolidColorQuad(SK_ColorBLACK)};
-  test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
-
-  SubmitCompositorFrame(support_.get(), root_passes, arraysize(root_passes),
-                        root_local_surface_id_);
-
-  test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE),
-                                 test::Quad::SolidColorQuad(SK_ColorGREEN),
-                                 test::Quad::SolidColorQuad(SK_ColorBLACK)};
-  test::Pass expected_passes[] = {
-      test::Pass(expected_quads, arraysize(expected_quads))};
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  viz::SurfaceId ids[] = {root_surface_id, embedded_surface_id};
-  AggregateAndVerify(
-      expected_passes, arraysize(expected_passes), ids, arraysize(ids));
-
-  embedded_support->EvictCurrentSurface();
-}
-
-// This test verifies that in the absence of a primary Surface,
-// SurfaceAggregator will embed a fallback Surface, if available. If the primary
-// Surface is available, though, the fallback will not be used.
-TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReference) {
-  std::unique_ptr<CompositorFrameSinkSupport> primary_child_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId primary_child_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId primary_child_surface_id(
-      primary_child_support->frame_sink_id(), primary_child_local_surface_id);
-
-  std::unique_ptr<CompositorFrameSinkSupport> fallback_child_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryFrameSinkId2, kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId fallback_child_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId fallback_child_surface_id(
-      fallback_child_support->frame_sink_id(), fallback_child_local_surface_id);
-
-  test::Quad fallback_child_quads[] = {test::Quad::SolidColorQuad(SK_ColorRED)};
-  test::Pass fallback_child_passes[] = {
-      test::Pass(fallback_child_quads, arraysize(fallback_child_quads))};
-
-  // Submit a CompositorFrame to the fallback Surface containing a red
-  // SolidColorDrawQuad.
-  SubmitCompositorFrame(fallback_child_support.get(), fallback_child_passes,
-                        arraysize(fallback_child_passes),
-                        fallback_child_local_surface_id);
-
-  // Try to embed |primary_child_surface_id| and if unavailabe, embed
-  // |fallback_child_surface_id|.
-  test::Quad root_quads[] = {test::Quad::SurfaceQuad(
-      primary_child_surface_id, fallback_child_surface_id, 1.f)};
-  test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
-
-  SubmitCompositorFrame(support_.get(), root_passes, arraysize(root_passes),
-                        root_local_surface_id_);
-
-  // There is no CompositorFrame submitted to |primary_child_surface_id| and so
-  // |fallback_child_surface_id| will be embedded and we should see a red
-  // SolidColorDrawQuad.
-  test::Quad expected_quads1[] = {test::Quad::SolidColorQuad(SK_ColorRED)};
-  test::Pass expected_passes1[] = {
-      test::Pass(expected_quads1, arraysize(expected_quads1))};
-
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  viz::SurfaceId ids[] = {root_surface_id, primary_child_surface_id,
-                          fallback_child_surface_id};
-  AggregateAndVerify(expected_passes1, arraysize(expected_passes1), ids,
-                     arraysize(ids));
-
-  // Check that SurfaceObserver::OnSurfaceWillDraw was called only
-  // for the fallback surface.
-  EXPECT_FALSE(observer_.SurfaceWillDrawCalled(primary_child_surface_id));
-  EXPECT_TRUE(observer_.SurfaceWillDrawCalled(fallback_child_surface_id));
-
-  observer_.Reset();
-
-  test::Quad primary_child_quads[] = {
-      test::Quad::SolidColorQuad(SK_ColorGREEN)};
-  test::Pass primary_child_passes[] = {
-      test::Pass(primary_child_quads, arraysize(primary_child_quads))};
-
-  // Submit a CompositorFrame to the primary Surface containing a green
-  // SolidColorDrawQuad.
-  SubmitCompositorFrame(primary_child_support.get(), primary_child_passes,
-                        arraysize(primary_child_passes),
-                        primary_child_local_surface_id);
-
-  // Now that the primary Surface has a CompositorFrame, we expect
-  // SurfaceAggregator to embed the primary Surface, and drop the fallback
-  // Surface.
-  test::Quad expected_quads2[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)};
-  test::Pass expected_passes2[] = {
-      test::Pass(expected_quads2, arraysize(expected_quads2))};
-  AggregateAndVerify(expected_passes2, arraysize(expected_passes2), ids,
-                     arraysize(ids));
-
-  // Check that SurfaceObserver::OnSurfaceWillDraw was called only
-  // for the primary surface.
-  EXPECT_TRUE(observer_.SurfaceWillDrawCalled(primary_child_surface_id));
-  EXPECT_FALSE(observer_.SurfaceWillDrawCalled(fallback_child_surface_id));
-
-  primary_child_support->EvictCurrentSurface();
-  fallback_child_support->EvictCurrentSurface();
-}
-
-// This test verifies that in the presence of both primary Surface and fallback
-// Surface, the fallback will not be used.
-TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReferenceWithPrimary) {
-  std::unique_ptr<CompositorFrameSinkSupport> primary_child_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId primary_child_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId primary_child_surface_id(
-      primary_child_support->frame_sink_id(), primary_child_local_surface_id);
-  test::Quad primary_child_quads[] = {
-      test::Quad::SolidColorQuad(SK_ColorGREEN)};
-  test::Pass primary_child_passes[] = {
-      test::Pass(primary_child_quads, arraysize(primary_child_quads))};
-
-  // Submit a CompositorFrame to the primary Surface containing a green
-  // SolidColorDrawQuad.
-  SubmitCompositorFrame(primary_child_support.get(), primary_child_passes,
-                        arraysize(primary_child_passes),
-                        primary_child_local_surface_id);
-
-  std::unique_ptr<CompositorFrameSinkSupport> fallback_child_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryFrameSinkId2, kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId fallback_child_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId fallback_child_surface_id(
-      fallback_child_support->frame_sink_id(), fallback_child_local_surface_id);
-
-  test::Quad fallback_child_quads[] = {test::Quad::SolidColorQuad(SK_ColorRED)};
-  test::Pass fallback_child_passes[] = {
-      test::Pass(fallback_child_quads, arraysize(fallback_child_quads))};
-
-  // Submit a CompositorFrame to the fallback Surface containing a red
-  // SolidColorDrawQuad.
-  SubmitCompositorFrame(fallback_child_support.get(), fallback_child_passes,
-                        arraysize(fallback_child_passes),
-                        fallback_child_local_surface_id);
-
-  // Try to embed |primary_child_surface_id| and if unavailabe, embed
-  // |fallback_child_surface_id|.
-  test::Quad root_quads[] = {test::Quad::SurfaceQuad(
-      primary_child_surface_id, fallback_child_surface_id, 1.f)};
-  test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
-
-  SubmitCompositorFrame(support_.get(), root_passes, arraysize(root_passes),
-                        root_local_surface_id_);
-
-  // The CompositorFrame is submitted to |primary_child_surface_id|, so
-  // |fallback_child_surface_id| will not be used and we should see a green
-  // SolidColorDrawQuad.
-  test::Quad expected_quads1[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)};
-  test::Pass expected_passes1[] = {
-      test::Pass(expected_quads1, arraysize(expected_quads1))};
-
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  viz::SurfaceId ids[] = {root_surface_id, primary_child_surface_id,
-                          fallback_child_surface_id};
-  AggregateAndVerify(expected_passes1, arraysize(expected_passes1), ids,
-                     arraysize(ids));
-
-  primary_child_support->EvictCurrentSurface();
-  fallback_child_support->EvictCurrentSurface();
-}
-
-TEST_F(SurfaceAggregatorValidSurfaceTest, CopyRequest) {
-  std::unique_ptr<CompositorFrameSinkSupport> embedded_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId embedded_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
-                                     embedded_local_surface_id);
-
-  test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)};
-  test::Pass embedded_passes[] = {
-      test::Pass(embedded_quads, arraysize(embedded_quads))};
-
-  SubmitCompositorFrame(embedded_support.get(), embedded_passes,
-                        arraysize(embedded_passes), embedded_local_surface_id);
-  std::unique_ptr<CopyOutputRequest> copy_request(
-      CopyOutputRequest::CreateEmptyRequest());
-  CopyOutputRequest* copy_request_ptr = copy_request.get();
-  embedded_support->RequestCopyOfSurface(std::move(copy_request));
-
-  test::Quad root_quads[] = {
-      test::Quad::SolidColorQuad(SK_ColorWHITE),
-      test::Quad::SurfaceQuad(embedded_surface_id, InvalidSurfaceId(), 1.f),
-      test::Quad::SolidColorQuad(SK_ColorBLACK)};
-  test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
-
-  SubmitCompositorFrame(support_.get(), root_passes, arraysize(root_passes),
-                        root_local_surface_id_);
-
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-  test::Quad expected_quads[] = {
-      test::Quad::SolidColorQuad(SK_ColorWHITE),
-      test::Quad::RenderPassQuad(aggregated_frame.render_pass_list[0]->id),
-      test::Quad::SolidColorQuad(SK_ColorBLACK)};
-  test::Pass expected_passes[] = {
-      test::Pass(embedded_quads, arraysize(embedded_quads)),
-      test::Pass(expected_quads, arraysize(expected_quads))};
-  TestPassesMatchExpectations(expected_passes, arraysize(expected_passes),
-                              &aggregated_frame.render_pass_list);
-  ASSERT_EQ(2u, aggregated_frame.render_pass_list.size());
-  ASSERT_EQ(1u, aggregated_frame.render_pass_list[0]->copy_requests.size());
-  DCHECK_EQ(copy_request_ptr,
-            aggregated_frame.render_pass_list[0]->copy_requests[0].get());
-
-  viz::SurfaceId surface_ids[] = {root_surface_id, embedded_surface_id};
-  EXPECT_EQ(arraysize(surface_ids),
-            aggregator_.previous_contained_surfaces().size());
-  for (size_t i = 0; i < arraysize(surface_ids); i++) {
-    EXPECT_TRUE(
-        aggregator_.previous_contained_surfaces().find(surface_ids[i]) !=
-        aggregator_.previous_contained_surfaces().end());
-  }
-
-  embedded_support->EvictCurrentSurface();
-}
-
-// Root surface may contain copy requests.
-TEST_F(SurfaceAggregatorValidSurfaceTest, RootCopyRequest) {
-  std::unique_ptr<CompositorFrameSinkSupport> embedded_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryFrameSinkId2, kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId embedded_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
-                                     embedded_local_surface_id);
-
-  test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)};
-  test::Pass embedded_passes[] = {
-      test::Pass(embedded_quads, arraysize(embedded_quads))};
-
-  SubmitCompositorFrame(embedded_support.get(), embedded_passes,
-                        arraysize(embedded_passes), embedded_local_surface_id);
-  std::unique_ptr<CopyOutputRequest> copy_request(
-      CopyOutputRequest::CreateEmptyRequest());
-  CopyOutputRequest* copy_request_ptr = copy_request.get();
-  std::unique_ptr<CopyOutputRequest> copy_request2(
-      CopyOutputRequest::CreateEmptyRequest());
-  CopyOutputRequest* copy_request2_ptr = copy_request2.get();
-
-  test::Quad root_quads[] = {
-      test::Quad::SolidColorQuad(SK_ColorWHITE),
-      test::Quad::SurfaceQuad(embedded_surface_id, InvalidSurfaceId(), 1.f),
-      test::Quad::SolidColorQuad(SK_ColorBLACK)};
-  test::Quad root_quads2[] = {test::Quad::SolidColorQuad(SK_ColorRED)};
-  test::Pass root_passes[] = {
-      test::Pass(root_quads, arraysize(root_quads), 1),
-      test::Pass(root_quads2, arraysize(root_quads2), 2)};
-  {
-    CompositorFrame frame = test::MakeEmptyCompositorFrame();
-    AddPasses(&frame.render_pass_list, gfx::Rect(SurfaceSize()), root_passes,
-              arraysize(root_passes));
-    frame.render_pass_list[0]->copy_requests.push_back(std::move(copy_request));
-    frame.render_pass_list[1]->copy_requests.push_back(
-        std::move(copy_request2));
-
-    support_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
-  }
-
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-  test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE),
-                                 test::Quad::SolidColorQuad(SK_ColorGREEN),
-                                 test::Quad::SolidColorQuad(SK_ColorBLACK)};
-  test::Pass expected_passes[] = {
-      test::Pass(expected_quads, arraysize(expected_quads)),
-      test::Pass(root_quads2, arraysize(root_quads2))};
-  TestPassesMatchExpectations(expected_passes, arraysize(expected_passes),
-                              &aggregated_frame.render_pass_list);
-  ASSERT_EQ(2u, aggregated_frame.render_pass_list.size());
-  ASSERT_EQ(1u, aggregated_frame.render_pass_list[0]->copy_requests.size());
-  DCHECK_EQ(copy_request_ptr,
-            aggregated_frame.render_pass_list[0]->copy_requests[0].get());
-  ASSERT_EQ(1u, aggregated_frame.render_pass_list[1]->copy_requests.size());
-  DCHECK_EQ(copy_request2_ptr,
-            aggregated_frame.render_pass_list[1]->copy_requests[0].get());
-
-  viz::SurfaceId surface_ids[] = {root_surface_id, embedded_surface_id};
-  EXPECT_EQ(arraysize(surface_ids),
-            aggregator_.previous_contained_surfaces().size());
-  for (size_t i = 0; i < arraysize(surface_ids); i++) {
-    EXPECT_TRUE(
-        aggregator_.previous_contained_surfaces().find(surface_ids[i]) !=
-        aggregator_.previous_contained_surfaces().end());
-  }
-
-  // Ensure copy requests have been removed from root surface.
-  const CompositorFrame& original_frame = manager_.surface_manager()
-                                              ->GetSurfaceForId(root_surface_id)
-                                              ->GetActiveFrame();
-  const RenderPassList& original_pass_list = original_frame.render_pass_list;
-  ASSERT_EQ(2u, original_pass_list.size());
-  DCHECK(original_pass_list[0]->copy_requests.empty());
-  DCHECK(original_pass_list[1]->copy_requests.empty());
-
-  embedded_support->EvictCurrentSurface();
-}
-
-TEST_F(SurfaceAggregatorValidSurfaceTest, UnreferencedSurface) {
-  std::unique_ptr<CompositorFrameSinkSupport> embedded_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  std::unique_ptr<CompositorFrameSinkSupport> parent_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryFrameSinkId2, kRootIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId embedded_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
-                                     embedded_local_surface_id);
-  viz::SurfaceId nonexistent_surface_id(support_->frame_sink_id(),
-                                        allocator_.GenerateId());
-
-  test::Quad embedded_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN)};
-  test::Pass embedded_passes[] = {
-      test::Pass(embedded_quads, arraysize(embedded_quads))};
-
-  SubmitCompositorFrame(embedded_support.get(), embedded_passes,
-                        arraysize(embedded_passes), embedded_local_surface_id);
-  std::unique_ptr<CopyOutputRequest> copy_request(
-      CopyOutputRequest::CreateEmptyRequest());
-  CopyOutputRequest* copy_request_ptr = copy_request.get();
-  embedded_support->RequestCopyOfSurface(std::move(copy_request));
-
-  viz::LocalSurfaceId parent_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId parent_surface_id(parent_support->frame_sink_id(),
-                                   parent_local_surface_id);
-
-  test::Quad parent_quads[] = {
-      test::Quad::SolidColorQuad(SK_ColorGRAY),
-      test::Quad::SurfaceQuad(embedded_surface_id, InvalidSurfaceId(), 1.f),
-      test::Quad::SolidColorQuad(SK_ColorLTGRAY)};
-  test::Pass parent_passes[] = {
-      test::Pass(parent_quads, arraysize(parent_quads))};
-
-  {
-    CompositorFrame frame = test::MakeEmptyCompositorFrame();
-
-    AddPasses(&frame.render_pass_list, gfx::Rect(SurfaceSize()), parent_passes,
-              arraysize(parent_passes));
-
-    frame.metadata.referenced_surfaces.push_back(embedded_surface_id);
-
-    parent_support->SubmitCompositorFrame(parent_local_surface_id,
-                                          std::move(frame));
-  }
-
-  test::Quad root_quads[] = {test::Quad::SolidColorQuad(SK_ColorWHITE),
-                             test::Quad::SolidColorQuad(SK_ColorBLACK)};
-  test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
-
-  {
-    CompositorFrame frame = test::MakeEmptyCompositorFrame();
-    AddPasses(&frame.render_pass_list, gfx::Rect(SurfaceSize()), root_passes,
-              arraysize(root_passes));
-
-    frame.metadata.referenced_surfaces.push_back(parent_surface_id);
-    // Reference to Surface ID of a Surface that doesn't exist should be
-    // included in previous_contained_surfaces, but otherwise ignored.
-    frame.metadata.referenced_surfaces.push_back(nonexistent_surface_id);
-
-    support_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
-  }
-
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-  // First pass should come from surface that had a copy request but was not
-  // referenced directly. The second pass comes from the root surface.
-  // parent_quad should be ignored because it is neither referenced through a
-  // SurfaceDrawQuad nor has a copy request on it.
-  test::Pass expected_passes[] = {
-      test::Pass(embedded_quads, arraysize(embedded_quads)),
-      test::Pass(root_quads, arraysize(root_quads))};
-  TestPassesMatchExpectations(expected_passes, arraysize(expected_passes),
-                              &aggregated_frame.render_pass_list);
-  ASSERT_EQ(2u, aggregated_frame.render_pass_list.size());
-  ASSERT_EQ(1u, aggregated_frame.render_pass_list[0]->copy_requests.size());
-  DCHECK_EQ(copy_request_ptr,
-            aggregated_frame.render_pass_list[0]->copy_requests[0].get());
-
-  viz::SurfaceId surface_ids[] = {
-      viz::SurfaceId(support_->frame_sink_id(), root_local_surface_id_),
-      parent_surface_id, embedded_surface_id, nonexistent_surface_id};
-  EXPECT_EQ(arraysize(surface_ids),
-            aggregator_.previous_contained_surfaces().size());
-  for (size_t i = 0; i < arraysize(surface_ids); i++) {
-    EXPECT_TRUE(
-        aggregator_.previous_contained_surfaces().find(surface_ids[i]) !=
-        aggregator_.previous_contained_surfaces().end());
-  }
-
-  embedded_support->EvictCurrentSurface();
-  parent_support->EvictCurrentSurface();
-}
-
-// This tests referencing a surface that has multiple render passes.
-TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) {
-  viz::LocalSurfaceId embedded_local_surface_id = child_allocator_.GenerateId();
-  viz::SurfaceId embedded_surface_id(child_support_->frame_sink_id(),
-                                     embedded_local_surface_id);
-
-  int pass_ids[] = {1, 2, 3};
-
-  test::Quad embedded_quads[][2] = {
-      {test::Quad::SolidColorQuad(1), test::Quad::SolidColorQuad(2)},
-      {test::Quad::SolidColorQuad(3), test::Quad::RenderPassQuad(pass_ids[0])},
-      {test::Quad::SolidColorQuad(4), test::Quad::RenderPassQuad(pass_ids[1])}};
-  test::Pass embedded_passes[] = {
-      test::Pass(embedded_quads[0], arraysize(embedded_quads[0]), pass_ids[0]),
-      test::Pass(embedded_quads[1], arraysize(embedded_quads[1]), pass_ids[1]),
-      test::Pass(embedded_quads[2], arraysize(embedded_quads[2]), pass_ids[2])};
-
-  SubmitCompositorFrame(child_support_.get(), embedded_passes,
-                        arraysize(embedded_passes), embedded_local_surface_id);
-
-  test::Quad root_quads[][2] = {
-      {test::Quad::SolidColorQuad(5), test::Quad::SolidColorQuad(6)},
-      {test::Quad::SurfaceQuad(embedded_surface_id, InvalidSurfaceId(), 1.f),
-       test::Quad::RenderPassQuad(pass_ids[0])},
-      {test::Quad::SolidColorQuad(7), test::Quad::RenderPassQuad(pass_ids[1])}};
-  test::Pass root_passes[] = {
-      test::Pass(root_quads[0], arraysize(root_quads[0]), pass_ids[0]),
-      test::Pass(root_quads[1], arraysize(root_quads[1]), pass_ids[1]),
-      test::Pass(root_quads[2], arraysize(root_quads[2]), pass_ids[2])};
-
-  SubmitCompositorFrame(support_.get(), root_passes, arraysize(root_passes),
-                        root_local_surface_id_);
-
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-  const RenderPassList& aggregated_pass_list =
-      aggregated_frame.render_pass_list;
-
-  ASSERT_EQ(5u, aggregated_pass_list.size());
-  RenderPassId actual_pass_ids[] = {
-      aggregated_pass_list[0]->id, aggregated_pass_list[1]->id,
-      aggregated_pass_list[2]->id, aggregated_pass_list[3]->id,
-      aggregated_pass_list[4]->id};
-  for (size_t i = 0; i < 5; ++i) {
-    for (size_t j = 0; j < i; ++j) {
-      EXPECT_NE(actual_pass_ids[i], actual_pass_ids[j]);
-    }
-  }
-
-  {
-    SCOPED_TRACE("First pass");
-    // The first pass will just be the first pass from the root surfaces quad
-    // with no render pass quads to remap.
-    TestPassMatchesExpectations(root_passes[0], aggregated_pass_list[0].get());
-  }
-
-  {
-    SCOPED_TRACE("Second pass");
-    // The next two passes will be from the embedded surface since we have to
-    // draw those passes before they are referenced from the render pass draw
-    // quad embedded into the root surface's second pass.
-    // First, there's the first embedded pass which doesn't reference anything
-    // else.
-    TestPassMatchesExpectations(embedded_passes[0],
-                                aggregated_pass_list[1].get());
-  }
-
-  {
-    SCOPED_TRACE("Third pass");
-    const QuadList& third_pass_quad_list = aggregated_pass_list[2]->quad_list;
-    ASSERT_EQ(2u, third_pass_quad_list.size());
-    TestQuadMatchesExpectations(embedded_quads[1][0],
-                                third_pass_quad_list.ElementAt(0));
-
-    // This render pass pass quad will reference the first pass from the
-    // embedded surface, which is the second pass in the aggregated frame.
-    ASSERT_EQ(DrawQuad::RENDER_PASS,
-              third_pass_quad_list.ElementAt(1)->material);
-    const RenderPassDrawQuad* third_pass_render_pass_draw_quad =
-        RenderPassDrawQuad::MaterialCast(third_pass_quad_list.ElementAt(1));
-    EXPECT_EQ(actual_pass_ids[1],
-              third_pass_render_pass_draw_quad->render_pass_id);
-  }
-
-  {
-    SCOPED_TRACE("Fourth pass");
-    // The fourth pass will have aggregated quads from the root surface's second
-    // pass and the embedded surface's first pass.
-    const QuadList& fourth_pass_quad_list = aggregated_pass_list[3]->quad_list;
-    ASSERT_EQ(3u, fourth_pass_quad_list.size());
-
-    // The first quad will be the yellow quad from the embedded surface's last
-    // pass.
-    TestQuadMatchesExpectations(embedded_quads[2][0],
-                                fourth_pass_quad_list.ElementAt(0));
-
-    // The next quad will be a render pass quad referencing the second pass from
-    // the embedded surface, which is the third pass in the aggregated frame.
-    ASSERT_EQ(DrawQuad::RENDER_PASS,
-              fourth_pass_quad_list.ElementAt(1)->material);
-    const RenderPassDrawQuad* fourth_pass_first_render_pass_draw_quad =
-        RenderPassDrawQuad::MaterialCast(fourth_pass_quad_list.ElementAt(1));
-    EXPECT_EQ(actual_pass_ids[2],
-              fourth_pass_first_render_pass_draw_quad->render_pass_id);
-
-    // The last quad will be a render pass quad referencing the first pass from
-    // the root surface, which is the first pass overall.
-    ASSERT_EQ(DrawQuad::RENDER_PASS,
-              fourth_pass_quad_list.ElementAt(2)->material);
-    const RenderPassDrawQuad* fourth_pass_second_render_pass_draw_quad =
-        RenderPassDrawQuad::MaterialCast(fourth_pass_quad_list.ElementAt(2));
-    EXPECT_EQ(actual_pass_ids[0],
-              fourth_pass_second_render_pass_draw_quad->render_pass_id);
-  }
-
-  {
-    SCOPED_TRACE("Fifth pass");
-    const QuadList& fifth_pass_quad_list = aggregated_pass_list[4]->quad_list;
-    ASSERT_EQ(2u, fifth_pass_quad_list.size());
-
-    TestQuadMatchesExpectations(root_quads[2][0],
-                                fifth_pass_quad_list.ElementAt(0));
-
-    // The last quad in the last pass will reference the second pass from the
-    // root surface, which after aggregating is the fourth pass in the overall
-    // list.
-    ASSERT_EQ(DrawQuad::RENDER_PASS,
-              fifth_pass_quad_list.ElementAt(1)->material);
-    const RenderPassDrawQuad* fifth_pass_render_pass_draw_quad =
-        RenderPassDrawQuad::MaterialCast(fifth_pass_quad_list.ElementAt(1));
-    EXPECT_EQ(actual_pass_ids[3],
-              fifth_pass_render_pass_draw_quad->render_pass_id);
-  }
-}
-
-// Tests an invalid surface reference in a frame. The surface quad should just
-// be dropped.
-TEST_F(SurfaceAggregatorValidSurfaceTest, InvalidSurfaceReference) {
-  test::Quad quads[] = {
-      test::Quad::SolidColorQuad(SK_ColorGREEN),
-      test::Quad::SurfaceQuad(InvalidSurfaceId(), InvalidSurfaceId(), 1.f),
-      test::Quad::SolidColorQuad(SK_ColorBLUE)};
-  test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
-
-  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
-                        root_local_surface_id_);
-
-  test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
-                                 test::Quad::SolidColorQuad(SK_ColorBLUE)};
-  test::Pass expected_passes[] = {
-      test::Pass(expected_quads, arraysize(expected_quads))};
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  viz::SurfaceId ids[] = {root_surface_id, InvalidSurfaceId()};
-
-  AggregateAndVerify(
-      expected_passes, arraysize(expected_passes), ids, arraysize(ids));
-}
-
-// Tests a reference to a valid surface with no submitted frame. This quad
-// should also just be dropped.
-TEST_F(SurfaceAggregatorValidSurfaceTest, ValidSurfaceReferenceWithNoFrame) {
-  viz::LocalSurfaceId empty_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId surface_with_no_frame_id(support_->frame_sink_id(),
-                                          empty_local_surface_id);
-
-  test::Quad quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
-                        test::Quad::SurfaceQuad(surface_with_no_frame_id,
-                                                InvalidSurfaceId(), 1.f),
-                        test::Quad::SolidColorQuad(SK_ColorBLUE)};
-  test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
-
-  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
-                        root_local_surface_id_);
-
-  test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorGREEN),
-                                 test::Quad::SolidColorQuad(SK_ColorBLUE)};
-  test::Pass expected_passes[] = {
-      test::Pass(expected_quads, arraysize(expected_quads))};
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  viz::SurfaceId ids[] = {root_surface_id, surface_with_no_frame_id};
-  AggregateAndVerify(
-      expected_passes, arraysize(expected_passes), ids, arraysize(ids));
-}
-
-// Tests a surface quad referencing itself, generating a trivial cycle.
-// The quad creating the cycle should be dropped from the final frame.
-TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleCyclicalReference) {
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  test::Quad quads[] = {
-      test::Quad::SurfaceQuad(root_surface_id, InvalidSurfaceId(), 1.f),
-      test::Quad::SolidColorQuad(SK_ColorYELLOW)};
-  test::Pass passes[] = {test::Pass(quads, arraysize(quads))};
-
-  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
-                        root_local_surface_id_);
-
-  test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorYELLOW)};
-  test::Pass expected_passes[] = {
-      test::Pass(expected_quads, arraysize(expected_quads))};
-  viz::SurfaceId ids[] = {root_surface_id};
-  AggregateAndVerify(
-      expected_passes, arraysize(expected_passes), ids, arraysize(ids));
-}
-
-// Tests a more complex cycle with one intermediate surface.
-TEST_F(SurfaceAggregatorValidSurfaceTest, TwoSurfaceCyclicalReference) {
-  viz::LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId child_surface_id(child_support_->frame_sink_id(),
-                                  child_local_surface_id);
-
-  test::Quad parent_quads[] = {
-      test::Quad::SolidColorQuad(SK_ColorBLUE),
-      test::Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f),
-      test::Quad::SolidColorQuad(SK_ColorCYAN)};
-  test::Pass parent_passes[] = {
-      test::Pass(parent_quads, arraysize(parent_quads))};
-
-  SubmitCompositorFrame(support_.get(), parent_passes, arraysize(parent_passes),
-                        root_local_surface_id_);
-
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  test::Quad child_quads[] = {
-      test::Quad::SolidColorQuad(SK_ColorGREEN),
-      test::Quad::SurfaceQuad(root_surface_id, InvalidSurfaceId(), 1.f),
-      test::Quad::SolidColorQuad(SK_ColorMAGENTA)};
-  test::Pass child_passes[] = {test::Pass(child_quads, arraysize(child_quads))};
-
-  SubmitCompositorFrame(child_support_.get(), child_passes,
-                        arraysize(child_passes), child_local_surface_id);
-
-  // The child surface's reference to the root_surface_ will be dropped, so
-  // we'll end up with:
-  //   SK_ColorBLUE from the parent
-  //   SK_ColorGREEN from the child
-  //   SK_ColorMAGENTA from the child
-  //   SK_ColorCYAN from the parent
-  test::Quad expected_quads[] = {test::Quad::SolidColorQuad(SK_ColorBLUE),
-                                 test::Quad::SolidColorQuad(SK_ColorGREEN),
-                                 test::Quad::SolidColorQuad(SK_ColorMAGENTA),
-                                 test::Quad::SolidColorQuad(SK_ColorCYAN)};
-  test::Pass expected_passes[] = {
-      test::Pass(expected_quads, arraysize(expected_quads))};
-  viz::SurfaceId ids[] = {root_surface_id, child_surface_id};
-  AggregateAndVerify(
-      expected_passes, arraysize(expected_passes), ids, arraysize(ids));
-}
-
-// Tests that we map render pass IDs from different surfaces into a unified
-// namespace and update RenderPassDrawQuad's id references to match.
-TEST_F(SurfaceAggregatorValidSurfaceTest, RenderPassIdMapping) {
-  viz::LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId child_surface_id(child_support_->frame_sink_id(),
-                                  child_local_surface_id);
-
-  RenderPassId child_pass_id[] = {1u, 2u};
-  test::Quad child_quad[][1] = {{test::Quad::SolidColorQuad(SK_ColorGREEN)},
-                                {test::Quad::RenderPassQuad(child_pass_id[0])}};
-  test::Pass surface_passes[] = {
-      test::Pass(child_quad[0], arraysize(child_quad[0]), child_pass_id[0]),
-      test::Pass(child_quad[1], arraysize(child_quad[1]), child_pass_id[1])};
-
-  SubmitCompositorFrame(child_support_.get(), surface_passes,
-                        arraysize(surface_passes), child_local_surface_id);
-
-  // Pass IDs from the parent surface may collide with ones from the child.
-  RenderPassId parent_pass_id[] = {3u, 2u};
-  test::Quad parent_quad[][1] = {
-      {test::Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)},
-      {test::Quad::RenderPassQuad(parent_pass_id[0])}};
-  test::Pass parent_passes[] = {
-      test::Pass(parent_quad[0], arraysize(parent_quad[0]), parent_pass_id[0]),
-      test::Pass(parent_quad[1], arraysize(parent_quad[1]), parent_pass_id[1])};
-
-  SubmitCompositorFrame(support_.get(), parent_passes, arraysize(parent_passes),
-                        root_local_surface_id_);
-
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-  const RenderPassList& aggregated_pass_list =
-      aggregated_frame.render_pass_list;
-
-  ASSERT_EQ(3u, aggregated_pass_list.size());
-  RenderPassId actual_pass_ids[] = {aggregated_pass_list[0]->id,
-                                    aggregated_pass_list[1]->id,
-                                    aggregated_pass_list[2]->id};
-  // Make sure the aggregated frame's pass IDs are all unique.
-  for (size_t i = 0; i < 3; ++i) {
-    for (size_t j = 0; j < i; ++j) {
-      EXPECT_NE(actual_pass_ids[j], actual_pass_ids[i]) << "pass ids " << i
-                                                        << " and " << j;
-    }
-  }
-
-  // Make sure the render pass quads reference the remapped pass IDs.
-  DrawQuad* render_pass_quads[] = {aggregated_pass_list[1]->quad_list.front(),
-                                   aggregated_pass_list[2]->quad_list.front()};
-  ASSERT_EQ(render_pass_quads[0]->material, DrawQuad::RENDER_PASS);
-  EXPECT_EQ(
-      actual_pass_ids[0],
-      RenderPassDrawQuad::MaterialCast(render_pass_quads[0])->render_pass_id);
-
-  ASSERT_EQ(render_pass_quads[1]->material, DrawQuad::RENDER_PASS);
-  EXPECT_EQ(
-      actual_pass_ids[1],
-      RenderPassDrawQuad::MaterialCast(render_pass_quads[1])->render_pass_id);
-}
-
-void AddSolidColorQuadWithBlendMode(const gfx::Size& size,
-                                    RenderPass* pass,
-                                    const SkBlendMode blend_mode) {
-  const gfx::Transform layer_to_target_transform;
-  const gfx::Rect layer_rect(size);
-  const gfx::Rect visible_layer_rect(size);
-  const gfx::Rect clip_rect(size);
-
-  bool is_clipped = false;
-  float opacity = 1.f;
-
-  bool force_anti_aliasing_off = false;
-  SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
-  sqs->SetAll(layer_to_target_transform, layer_rect, visible_layer_rect,
-              clip_rect, is_clipped, opacity, blend_mode, 0);
-
-  SolidColorDrawQuad* color_quad =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  color_quad->SetNew(pass->shared_quad_state_list.back(), visible_layer_rect,
-                     visible_layer_rect, SK_ColorGREEN,
-                     force_anti_aliasing_off);
-}
-
-// This tests that we update shared quad state pointers correctly within
-// aggregated passes.  The shared quad state list on the aggregated pass will
-// include the shared quad states from each pass in one list so the quads will
-// end up pointed to shared quad state objects at different offsets. This test
-// uses the blend_mode value stored on the shared quad state to track the shared
-// quad state, but anything saved on the shared quad state would work.
-//
-// This test has 4 surfaces in the following structure:
-// root_surface -> quad with kClear_Mode,
-//                 [child_one_surface],
-//                 quad with kDstOver_Mode,
-//                 [child_two_surface],
-//                 quad with kDstIn_Mode
-// child_one_surface -> quad with kSrc_Mode,
-//                      [grandchild_surface],
-//                      quad with kSrcOver_Mode
-// child_two_surface -> quad with kSrcIn_Mode
-// grandchild_surface -> quad with kDst_Mode
-//
-// Resulting in the following aggregated pass:
-//  quad_root_0       - blend_mode kClear_Mode
-//  quad_child_one_0  - blend_mode kSrc_Mode
-//  quad_grandchild_0 - blend_mode kDst_Mode
-//  quad_child_one_1  - blend_mode kSrcOver_Mode
-//  quad_root_1       - blend_mode kDstOver_Mode
-//  quad_child_two_0  - blend_mode kSrcIn_Mode
-//  quad_root_2       - blend_mode kDstIn_Mode
-TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) {
-  const SkBlendMode blend_modes[] = {
-      SkBlendMode::kClear,    // 0
-      SkBlendMode::kSrc,      // 1
-      SkBlendMode::kDst,      // 2
-      SkBlendMode::kSrcOver,  // 3
-      SkBlendMode::kDstOver,  // 4
-      SkBlendMode::kSrcIn,    // 5
-      SkBlendMode::kDstIn,    // 6
-  };
-  std::unique_ptr<CompositorFrameSinkSupport> grandchild_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  std::unique_ptr<CompositorFrameSinkSupport> child_one_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryFrameSinkId2, kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  std::unique_ptr<CompositorFrameSinkSupport> child_two_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryFrameSinkId3, kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  int pass_id = 1;
-  viz::LocalSurfaceId grandchild_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId grandchild_surface_id(grandchild_support->frame_sink_id(),
-                                       grandchild_local_surface_id);
-
-  std::unique_ptr<RenderPass> grandchild_pass = RenderPass::Create();
-  gfx::Rect output_rect(SurfaceSize());
-  gfx::Rect damage_rect(SurfaceSize());
-  gfx::Transform transform_to_root_target;
-  grandchild_pass->SetNew(pass_id, output_rect, damage_rect,
-                          transform_to_root_target);
-  AddSolidColorQuadWithBlendMode(
-      SurfaceSize(), grandchild_pass.get(), blend_modes[2]);
-  QueuePassAsFrame(std::move(grandchild_pass), grandchild_local_surface_id,
-                   grandchild_support.get());
-
-  viz::LocalSurfaceId child_one_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId child_one_surface_id(child_one_support->frame_sink_id(),
-                                      child_one_local_surface_id);
-
-  std::unique_ptr<RenderPass> child_one_pass = RenderPass::Create();
-  child_one_pass->SetNew(pass_id, output_rect, damage_rect,
-                         transform_to_root_target);
-  AddSolidColorQuadWithBlendMode(
-      SurfaceSize(), child_one_pass.get(), blend_modes[1]);
-  SurfaceDrawQuad* grandchild_surface_quad =
-      child_one_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-  grandchild_surface_quad->SetNew(
-      child_one_pass->shared_quad_state_list.back(), gfx::Rect(SurfaceSize()),
-      gfx::Rect(SurfaceSize()), grandchild_surface_id,
-      SurfaceDrawQuadType::PRIMARY, nullptr);
-  AddSolidColorQuadWithBlendMode(
-      SurfaceSize(), child_one_pass.get(), blend_modes[3]);
-  QueuePassAsFrame(std::move(child_one_pass), child_one_local_surface_id,
-                   child_one_support.get());
-
-  viz::LocalSurfaceId child_two_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId child_two_surface_id(child_two_support->frame_sink_id(),
-                                      child_two_local_surface_id);
-
-  std::unique_ptr<RenderPass> child_two_pass = RenderPass::Create();
-  child_two_pass->SetNew(pass_id, output_rect, damage_rect,
-                         transform_to_root_target);
-  AddSolidColorQuadWithBlendMode(
-      SurfaceSize(), child_two_pass.get(), blend_modes[5]);
-  QueuePassAsFrame(std::move(child_two_pass), child_two_local_surface_id,
-                   child_two_support.get());
-
-  std::unique_ptr<RenderPass> root_pass = RenderPass::Create();
-  root_pass->SetNew(pass_id, output_rect, damage_rect,
-                    transform_to_root_target);
-
-  AddSolidColorQuadWithBlendMode(
-      SurfaceSize(), root_pass.get(), blend_modes[0]);
-  SurfaceDrawQuad* child_one_surface_quad =
-      root_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-  child_one_surface_quad->SetNew(root_pass->shared_quad_state_list.back(),
-                                 gfx::Rect(SurfaceSize()),
-                                 gfx::Rect(SurfaceSize()), child_one_surface_id,
-                                 SurfaceDrawQuadType::PRIMARY, nullptr);
-  AddSolidColorQuadWithBlendMode(
-      SurfaceSize(), root_pass.get(), blend_modes[4]);
-  SurfaceDrawQuad* child_two_surface_quad =
-      root_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-  child_two_surface_quad->SetNew(root_pass->shared_quad_state_list.back(),
-                                 gfx::Rect(SurfaceSize()),
-                                 gfx::Rect(SurfaceSize()), child_two_surface_id,
-                                 SurfaceDrawQuadType::PRIMARY, nullptr);
-  AddSolidColorQuadWithBlendMode(
-      SurfaceSize(), root_pass.get(), blend_modes[6]);
-
-  QueuePassAsFrame(std::move(root_pass), root_local_surface_id_,
-                   support_.get());
-
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-  const RenderPassList& aggregated_pass_list =
-      aggregated_frame.render_pass_list;
-
-  ASSERT_EQ(1u, aggregated_pass_list.size());
-
-  const QuadList& aggregated_quad_list = aggregated_pass_list[0]->quad_list;
-
-  ASSERT_EQ(7u, aggregated_quad_list.size());
-
-  for (auto iter = aggregated_quad_list.cbegin();
-       iter != aggregated_quad_list.cend();
-       ++iter) {
-    EXPECT_EQ(blend_modes[iter.index()], iter->shared_quad_state->blend_mode)
-        << iter.index();
-  }
-
-  grandchild_support->EvictCurrentSurface();
-  child_one_support->EvictCurrentSurface();
-  child_two_support->EvictCurrentSurface();
-}
-
-// This tests that when aggregating a frame with multiple render passes that we
-// map the transforms for the root pass but do not modify the transform on child
-// passes.
-//
-// The root surface has one pass with a surface quad transformed by +10 in the y
-// direction.
-//
-// The middle surface has one pass with a surface quad scaled by 2 in the x
-// and 3 in the y directions.
-//
-// The child surface has two passes. The first pass has a quad with a transform
-// of +5 in the x direction. The second pass has a reference to the first pass'
-// pass id and a transform of +8 in the x direction.
-//
-// After aggregation, the child surface's root pass quad should have all
-// transforms concatenated for a total transform of +23 x, +10 y. The
-// contributing render pass' transform in the aggregate frame should not be
-// affected.
-TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) {
-  std::unique_ptr<CompositorFrameSinkSupport> middle_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryMiddleFrameSinkId, kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  // Innermost child surface.
-  viz::LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId child_surface_id(child_support_->frame_sink_id(),
-                                  child_local_surface_id);
-  {
-    int child_pass_id[] = {1, 2};
-    test::Quad child_quads[][1] = {
-        {test::Quad::SolidColorQuad(SK_ColorGREEN)},
-        {test::Quad::RenderPassQuad(child_pass_id[0])},
-    };
-    test::Pass child_passes[] = {
-        test::Pass(child_quads[0], arraysize(child_quads[0]), child_pass_id[0]),
-        test::Pass(child_quads[1], arraysize(child_quads[1]),
-                   child_pass_id[1])};
-
-    CompositorFrame child_frame = test::MakeEmptyCompositorFrame();
-    AddPasses(&child_frame.render_pass_list, gfx::Rect(SurfaceSize()),
-              child_passes, arraysize(child_passes));
-
-    RenderPass* child_nonroot_pass = child_frame.render_pass_list[0].get();
-    child_nonroot_pass->transform_to_root_target.Translate(8, 0);
-    SharedQuadState* child_nonroot_pass_sqs =
-        child_nonroot_pass->shared_quad_state_list.front();
-    child_nonroot_pass_sqs->quad_to_target_transform.Translate(5, 0);
-
-    RenderPass* child_root_pass = child_frame.render_pass_list[1].get();
-    SharedQuadState* child_root_pass_sqs =
-        child_root_pass->shared_quad_state_list.front();
-    child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
-    child_root_pass_sqs->is_clipped = true;
-    child_root_pass_sqs->clip_rect = gfx::Rect(0, 0, 5, 5);
-
-    child_support_->SubmitCompositorFrame(child_local_surface_id,
-                                          std::move(child_frame));
-  }
-
-  // Middle child surface.
-  viz::LocalSurfaceId middle_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId middle_surface_id(middle_support->frame_sink_id(),
-                                   middle_local_surface_id);
-  {
-    test::Quad middle_quads[] = {
-        test::Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
-    test::Pass middle_passes[] = {
-        test::Pass(middle_quads, arraysize(middle_quads)),
-    };
-
-    CompositorFrame middle_frame = test::MakeEmptyCompositorFrame();
-    AddPasses(&middle_frame.render_pass_list, gfx::Rect(SurfaceSize()),
-              middle_passes, arraysize(middle_passes));
-
-    RenderPass* middle_root_pass = middle_frame.render_pass_list[0].get();
-    middle_root_pass->quad_list.ElementAt(0)->visible_rect =
-        gfx::Rect(0, 1, 100, 7);
-    SharedQuadState* middle_root_pass_sqs =
-        middle_root_pass->shared_quad_state_list.front();
-    middle_root_pass_sqs->quad_to_target_transform.Scale(2, 3);
-
-    middle_support->SubmitCompositorFrame(middle_local_surface_id,
-                                          std::move(middle_frame));
-  }
-
-  // Root surface.
-  test::Quad secondary_quads[] = {
-      test::Quad::SolidColorQuad(1),
-      test::Quad::SurfaceQuad(middle_surface_id, InvalidSurfaceId(), 1.f)};
-  test::Quad root_quads[] = {test::Quad::SolidColorQuad(1)};
-  test::Pass root_passes[] = {
-      test::Pass(secondary_quads, arraysize(secondary_quads)),
-      test::Pass(root_quads, arraysize(root_quads))};
-
-  CompositorFrame root_frame = test::MakeEmptyCompositorFrame();
-  AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()), root_passes,
-            arraysize(root_passes));
-
-  root_frame.render_pass_list[0]
-      ->shared_quad_state_list.front()
-      ->quad_to_target_transform.Translate(0, 7);
-  root_frame.render_pass_list[0]
-      ->shared_quad_state_list.ElementAt(1)
-      ->quad_to_target_transform.Translate(0, 10);
-  root_frame.render_pass_list[0]->quad_list.ElementAt(1)->visible_rect =
-      gfx::Rect(0, 0, 8, 100);
-
-  root_frame.render_pass_list[0]->transform_to_root_target.Translate(10, 5);
-
-  support_->SubmitCompositorFrame(root_local_surface_id_,
-                                  std::move(root_frame));
-
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-  const RenderPassList& aggregated_pass_list =
-      aggregated_frame.render_pass_list;
-
-  ASSERT_EQ(3u, aggregated_pass_list.size());
-
-  ASSERT_EQ(1u, aggregated_pass_list[0]->shared_quad_state_list.size());
-
-  // The first pass should have one shared quad state for the one solid color
-  // quad.
-  EXPECT_EQ(1u, aggregated_pass_list[0]->shared_quad_state_list.size());
-  // The second pass should have just two shared quad states. We'll
-  // verify the properties through the quads.
-  EXPECT_EQ(2u, aggregated_pass_list[1]->shared_quad_state_list.size());
-
-  EXPECT_EQ(1u, aggregated_pass_list[2]->shared_quad_state_list.size());
-
-  SharedQuadState* aggregated_first_pass_sqs =
-      aggregated_pass_list[0]->shared_quad_state_list.front();
-
-  // The first pass's transform should be unaffected by the embedding and still
-  // be a translation by +5 in the x direction.
-  gfx::Transform expected_aggregated_first_pass_sqs_transform;
-  expected_aggregated_first_pass_sqs_transform.Translate(5, 0);
-  EXPECT_EQ(expected_aggregated_first_pass_sqs_transform.ToString(),
-            aggregated_first_pass_sqs->quad_to_target_transform.ToString());
-
-  // The first pass's transform to the root target should include the aggregated
-  // transform, including the transform from the child pass to the root.
-  gfx::Transform expected_first_pass_transform_to_root_target;
-  expected_first_pass_transform_to_root_target.Translate(10, 5);
-  expected_first_pass_transform_to_root_target.Translate(0, 10);
-  expected_first_pass_transform_to_root_target.Scale(2, 3);
-  expected_first_pass_transform_to_root_target.Translate(8, 0);
-  EXPECT_EQ(expected_first_pass_transform_to_root_target.ToString(),
-            aggregated_pass_list[0]->transform_to_root_target.ToString());
-
-  ASSERT_EQ(2u, aggregated_pass_list[1]->quad_list.size());
-
-  gfx::Transform expected_root_pass_quad_transforms[2];
-  // The first quad in the root pass is the solid color quad from the original
-  // root surface. Its transform should be unaffected by the aggregation and
-  // still be +7 in the y direction.
-  expected_root_pass_quad_transforms[0].Translate(0, 7);
-  // The second quad in the root pass is aggregated from the child surface so
-  // its transform should be the combination of its original translation
-  // (0, 10), the middle surface draw quad's scale of (2, 3), and the
-  // child surface draw quad's translation (8, 0).
-  expected_root_pass_quad_transforms[1].Translate(0, 10);
-  expected_root_pass_quad_transforms[1].Scale(2, 3);
-  expected_root_pass_quad_transforms[1].Translate(8, 0);
-
-  for (auto iter = aggregated_pass_list[1]->quad_list.cbegin();
-       iter != aggregated_pass_list[1]->quad_list.cend();
-       ++iter) {
-    EXPECT_EQ(expected_root_pass_quad_transforms[iter.index()].ToString(),
-              iter->shared_quad_state->quad_to_target_transform.ToString())
-        << iter.index();
-  }
-
-  EXPECT_TRUE(
-      aggregated_pass_list[1]->shared_quad_state_list.ElementAt(1)->is_clipped);
-
-  // The second quad in the root pass is aggregated from the child, so its
-  // clip rect must be transformed by the child's translation/scale and
-  // clipped be the visible_rects for both children.
-  EXPECT_EQ(gfx::Rect(0, 13, 8, 12).ToString(),
-            aggregated_pass_list[1]
-                ->shared_quad_state_list.ElementAt(1)
-                ->clip_rect.ToString());
-
-  middle_support->EvictCurrentSurface();
-}
-
-// Tests that damage rects are aggregated correctly when surfaces change.
-TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
-  std::unique_ptr<CompositorFrameSinkSupport> parent_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryMiddleFrameSinkId, kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  test::Quad child_quads[] = {test::Quad::RenderPassQuad(1)};
-  test::Pass child_passes[] = {
-      test::Pass(child_quads, arraysize(child_quads), 1)};
-
-  CompositorFrame child_frame = test::MakeEmptyCompositorFrame();
-  AddPasses(&child_frame.render_pass_list, gfx::Rect(SurfaceSize()),
-            child_passes, arraysize(child_passes));
-
-  RenderPass* child_root_pass = child_frame.render_pass_list[0].get();
-  SharedQuadState* child_root_pass_sqs =
-      child_root_pass->shared_quad_state_list.front();
-  child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
-
-  viz::LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId child_surface_id(child_support_->frame_sink_id(),
-                                  child_local_surface_id);
-  child_support_->SubmitCompositorFrame(child_local_surface_id,
-                                        std::move(child_frame));
-
-  test::Quad parent_surface_quads[] = {
-      test::Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
-  test::Pass parent_surface_passes[] = {
-      test::Pass(parent_surface_quads, arraysize(parent_surface_quads), 1)};
-
-  // Parent surface is only used to test if the transform is applied correctly
-  // to the child surface's damage.
-  CompositorFrame parent_surface_frame = test::MakeEmptyCompositorFrame();
-  AddPasses(&parent_surface_frame.render_pass_list, gfx::Rect(SurfaceSize()),
-            parent_surface_passes, arraysize(parent_surface_passes));
-
-  viz::LocalSurfaceId parent_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId parent_surface_id(parent_support->frame_sink_id(),
-                                   parent_local_surface_id);
-  parent_support->SubmitCompositorFrame(parent_local_surface_id,
-                                        std::move(parent_surface_frame));
-
-  test::Quad root_surface_quads[] = {
-      test::Quad::SurfaceQuad(parent_surface_id, InvalidSurfaceId(), 1.f)};
-  test::Quad root_render_pass_quads[] = {test::Quad::RenderPassQuad(1)};
-
-  test::Pass root_passes[] = {
-      test::Pass(root_surface_quads, arraysize(root_surface_quads), 1),
-      test::Pass(root_render_pass_quads, arraysize(root_render_pass_quads), 2)};
-
-  CompositorFrame root_frame = test::MakeEmptyCompositorFrame();
-  AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()), root_passes,
-            arraysize(root_passes));
-
-  root_frame.render_pass_list[0]
-      ->shared_quad_state_list.front()
-      ->quad_to_target_transform.Translate(0, 10);
-  root_frame.render_pass_list[0]->damage_rect = gfx::Rect(5, 5, 10, 10);
-  root_frame.render_pass_list[1]->damage_rect = gfx::Rect(5, 5, 100, 100);
-
-  support_->SubmitCompositorFrame(root_local_surface_id_,
-                                  std::move(root_frame));
-
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-  const RenderPassList& aggregated_pass_list =
-      aggregated_frame.render_pass_list;
-
-  ASSERT_EQ(2u, aggregated_pass_list.size());
-
-  // Damage rect for first aggregation should contain entire root surface.
-  EXPECT_TRUE(
-      aggregated_pass_list[1]->damage_rect.Contains(gfx::Rect(SurfaceSize())));
-
-  {
-    CompositorFrame child_frame = test::MakeEmptyCompositorFrame();
-    AddPasses(&child_frame.render_pass_list, gfx::Rect(SurfaceSize()),
-              child_passes, arraysize(child_passes));
-
-    RenderPass* child_root_pass = child_frame.render_pass_list[0].get();
-    SharedQuadState* child_root_pass_sqs =
-        child_root_pass->shared_quad_state_list.front();
-    child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
-    child_root_pass->damage_rect = gfx::Rect(10, 10, 10, 10);
-
-    child_support_->SubmitCompositorFrame(child_local_surface_id,
-                                          std::move(child_frame));
-
-    viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                   root_local_surface_id_);
-    CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-    const RenderPassList& aggregated_pass_list =
-        aggregated_frame.render_pass_list;
-
-    ASSERT_EQ(2u, aggregated_pass_list.size());
-
-    // Outer surface didn't change, so transformed inner damage rect should be
-    // used.
-    EXPECT_EQ(gfx::Rect(10, 20, 10, 10).ToString(),
-              aggregated_pass_list[1]->damage_rect.ToString());
-  }
-
-  {
-    CompositorFrame root_frame = test::MakeEmptyCompositorFrame();
-    AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()),
-              root_passes, arraysize(root_passes));
-
-    root_frame.render_pass_list[0]
-        ->shared_quad_state_list.front()
-        ->quad_to_target_transform.Translate(0, 10);
-    root_frame.render_pass_list[0]->damage_rect = gfx::Rect(0, 0, 1, 1);
-
-    support_->SubmitCompositorFrame(root_local_surface_id_,
-                                    std::move(root_frame));
-  }
-
-  {
-    CompositorFrame root_frame = test::MakeEmptyCompositorFrame();
-    AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()),
-              root_passes, arraysize(root_passes));
-
-    root_frame.render_pass_list[0]
-        ->shared_quad_state_list.front()
-        ->quad_to_target_transform.Translate(0, 10);
-    root_frame.render_pass_list[0]->damage_rect = gfx::Rect(1, 1, 1, 1);
-
-    support_->SubmitCompositorFrame(root_local_surface_id_,
-                                    std::move(root_frame));
-
-    viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                   root_local_surface_id_);
-    CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-    const RenderPassList& aggregated_pass_list =
-        aggregated_frame.render_pass_list;
-
-    ASSERT_EQ(2u, aggregated_pass_list.size());
-
-    // The root surface was enqueued without being aggregated once, so it should
-    // be treated as completely damaged.
-    EXPECT_TRUE(aggregated_pass_list[1]->damage_rect.Contains(
-        gfx::Rect(SurfaceSize())));
-  }
-
-  // No Surface changed, so no damage should be given.
-  {
-    viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                   root_local_surface_id_);
-    CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-    const RenderPassList& aggregated_pass_list =
-        aggregated_frame.render_pass_list;
-
-    ASSERT_EQ(2u, aggregated_pass_list.size());
-
-    EXPECT_TRUE(aggregated_pass_list[1]->damage_rect.IsEmpty());
-  }
-
-  // SetFullDamageRectForSurface should cause the entire output to be
-  // marked as damaged.
-  {
-    aggregator_.SetFullDamageForSurface(root_surface_id);
-    CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-    const RenderPassList& aggregated_pass_list =
-        aggregated_frame.render_pass_list;
-
-    ASSERT_EQ(2u, aggregated_pass_list.size());
-
-    EXPECT_TRUE(aggregated_pass_list[1]->damage_rect.Contains(
-        gfx::Rect(SurfaceSize())));
-  }
-
-  parent_support->EvictCurrentSurface();
-}
-
-// Check that damage is correctly calculated for surfaces.
-TEST_F(SurfaceAggregatorValidSurfaceTest, SwitchSurfaceDamage) {
-  test::Quad root_render_pass_quads[] = {test::Quad::SolidColorQuad(1)};
-
-  test::Pass root_passes[] = {
-      test::Pass(root_render_pass_quads, arraysize(root_render_pass_quads), 2)};
-
-  CompositorFrame root_frame = test::MakeEmptyCompositorFrame();
-  AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()), root_passes,
-            arraysize(root_passes));
-
-  root_frame.render_pass_list[0]->damage_rect = gfx::Rect(5, 5, 100, 100);
-
-  support_->SubmitCompositorFrame(root_local_surface_id_,
-                                  std::move(root_frame));
-
-  {
-    viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                   root_local_surface_id_);
-    CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-    const RenderPassList& aggregated_pass_list =
-        aggregated_frame.render_pass_list;
-
-    ASSERT_EQ(1u, aggregated_pass_list.size());
-
-    // Damage rect for first aggregation should contain entire root surface.
-    EXPECT_TRUE(aggregated_pass_list[0]->damage_rect.Contains(
-        gfx::Rect(SurfaceSize())));
-  }
-
-  viz::LocalSurfaceId second_root_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId second_root_surface_id(support_->frame_sink_id(),
-                                        second_root_local_surface_id);
-  {
-    test::Quad root_render_pass_quads[] = {test::Quad::SolidColorQuad(1)};
-
-    test::Pass root_passes[] = {test::Pass(
-        root_render_pass_quads, arraysize(root_render_pass_quads), 2)};
-
-    CompositorFrame root_frame = test::MakeEmptyCompositorFrame();
-    AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()),
-              root_passes, arraysize(root_passes));
-
-    root_frame.render_pass_list[0]->damage_rect = gfx::Rect(1, 2, 3, 4);
-
-    support_->SubmitCompositorFrame(second_root_local_surface_id,
-                                    std::move(root_frame));
-  }
-  {
-    CompositorFrame aggregated_frame =
-        aggregator_.Aggregate(second_root_surface_id);
-
-    const RenderPassList& aggregated_pass_list =
-        aggregated_frame.render_pass_list;
-
-    ASSERT_EQ(1u, aggregated_pass_list.size());
-
-    EXPECT_EQ(gfx::Rect(1, 2, 3, 4), aggregated_pass_list[0]->damage_rect);
-  }
-  {
-    CompositorFrame aggregated_frame =
-        aggregator_.Aggregate(second_root_surface_id);
-
-    const RenderPassList& aggregated_pass_list =
-        aggregated_frame.render_pass_list;
-
-    ASSERT_EQ(1u, aggregated_pass_list.size());
-
-    // No new frame, so no new damage.
-    EXPECT_TRUE(aggregated_pass_list[0]->damage_rect.IsEmpty());
-  }
-}
-
-class SurfaceAggregatorPartialSwapTest
-    : public SurfaceAggregatorValidSurfaceTest {
- public:
-  SurfaceAggregatorPartialSwapTest()
-      : SurfaceAggregatorValidSurfaceTest(true) {}
-};
-
-// Tests that quads outside the damage rect are ignored.
-TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) {
-  viz::LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId child_surface_id(child_support_->frame_sink_id(),
-                                  child_local_surface_id);
-  // The child surface has three quads, one with a visible rect of 13,13 4x4 and
-  // the other other with a visible rect of 10,10 2x2 (relative to root target
-  // space), and one with a non-invertible transform.
-  {
-    int child_pass_id = 1;
-    test::Quad child_quads1[] = {test::Quad::RenderPassQuad(child_pass_id)};
-    test::Quad child_quads2[] = {test::Quad::RenderPassQuad(child_pass_id)};
-    test::Quad child_quads3[] = {test::Quad::RenderPassQuad(child_pass_id)};
-    test::Pass child_passes[] = {
-        test::Pass(child_quads1, arraysize(child_quads1), child_pass_id),
-        test::Pass(child_quads2, arraysize(child_quads2), child_pass_id),
-        test::Pass(child_quads3, arraysize(child_quads2), child_pass_id)};
-
-    RenderPassList child_pass_list;
-    AddPasses(&child_pass_list, gfx::Rect(SurfaceSize()), child_passes,
-              arraysize(child_passes));
-
-    child_pass_list[0]->quad_list.ElementAt(0)->visible_rect =
-        gfx::Rect(1, 1, 2, 2);
-    SharedQuadState* child_sqs =
-        child_pass_list[0]->shared_quad_state_list.ElementAt(0u);
-    child_sqs->quad_to_target_transform.Translate(1, 1);
-    child_sqs->quad_to_target_transform.Scale(2, 2);
-
-    child_pass_list[1]->quad_list.ElementAt(0)->visible_rect =
-        gfx::Rect(0, 0, 2, 2);
-
-    SharedQuadState* child_noninvertible_sqs =
-        child_pass_list[2]->shared_quad_state_list.ElementAt(0u);
-    child_noninvertible_sqs->quad_to_target_transform.matrix().setDouble(0, 0,
-                                                                         0.0);
-    EXPECT_FALSE(
-        child_noninvertible_sqs->quad_to_target_transform.IsInvertible());
-    child_pass_list[2]->quad_list.ElementAt(0)->visible_rect =
-        gfx::Rect(0, 0, 2, 2);
-
-    SubmitPassListAsFrame(child_support_.get(), child_local_surface_id,
-                          &child_pass_list);
-  }
-
-  {
-    test::Quad root_quads[] = {
-        test::Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
-
-    test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
-
-    RenderPassList root_pass_list;
-    AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes,
-              arraysize(root_passes));
-
-    RenderPass* root_pass = root_pass_list[0].get();
-    root_pass->shared_quad_state_list.front()
-        ->quad_to_target_transform.Translate(10, 10);
-    root_pass->damage_rect = gfx::Rect(0, 0, 1, 1);
-
-    SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
-                          &root_pass_list);
-  }
-
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id_);
-  CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-  const RenderPassList& aggregated_pass_list =
-      aggregated_frame.render_pass_list;
-
-  ASSERT_EQ(3u, aggregated_pass_list.size());
-
-  // Damage rect for first aggregation should contain entire root surface.
-  EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[2]->damage_rect);
-  EXPECT_EQ(1u, aggregated_pass_list[0]->quad_list.size());
-  EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size());
-  EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size());
-
-  // Create a root surface with a smaller damage rect.
-  {
-    test::Quad root_quads[] = {
-        test::Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
-
-    test::Pass root_passes[] = {test::Pass(root_quads, arraysize(root_quads))};
-
-    RenderPassList root_pass_list;
-    AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes,
-              arraysize(root_passes));
-
-    RenderPass* root_pass = root_pass_list[0].get();
-    root_pass->shared_quad_state_list.front()
-        ->quad_to_target_transform.Translate(10, 10);
-    root_pass->damage_rect = gfx::Rect(10, 10, 2, 2);
-    SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
-                          &root_pass_list);
-  }
-
-  {
-    CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-    const RenderPassList& aggregated_pass_list =
-        aggregated_frame.render_pass_list;
-
-    ASSERT_EQ(3u, aggregated_pass_list.size());
-
-    // Only first quad from surface is inside damage rect and should be
-    // included.
-    EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[2]->damage_rect);
-    EXPECT_EQ(0u, aggregated_pass_list[0]->quad_list.size());
-    EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size());
-    EXPECT_EQ(gfx::Rect(0, 0, 2, 2),
-              aggregated_pass_list[1]->quad_list.back()->visible_rect);
-    EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size());
-  }
-
-  // New child frame has same content and no damage, but has a
-  // CopyOutputRequest.
-  {
-    int child_pass_ids[] = {1, 2};
-    test::Quad child_quads1[] = {test::Quad::SolidColorQuad(1)};
-    test::Quad child_quads2[] = {test::Quad::RenderPassQuad(child_pass_ids[0])};
-    test::Pass child_passes[] = {
-        test::Pass(child_quads1, arraysize(child_quads1), child_pass_ids[0]),
-        test::Pass(child_quads2, arraysize(child_quads2), child_pass_ids[1])};
-
-    RenderPassList child_pass_list;
-    AddPasses(&child_pass_list, gfx::Rect(SurfaceSize()), child_passes,
-              arraysize(child_passes));
-
-    child_pass_list[0]->quad_list.ElementAt(0)->visible_rect =
-        gfx::Rect(1, 1, 2, 2);
-    SharedQuadState* child_sqs =
-        child_pass_list[0]->shared_quad_state_list.ElementAt(0u);
-    child_sqs->quad_to_target_transform.Translate(1, 1);
-    child_sqs->quad_to_target_transform.Scale(2, 2);
-
-    child_pass_list[1]->quad_list.ElementAt(0)->visible_rect =
-        gfx::Rect(0, 0, 2, 2);
-
-    RenderPass* child_root_pass = child_pass_list[1].get();
-
-    child_root_pass->copy_requests.push_back(
-        CopyOutputRequest::CreateEmptyRequest());
-    child_root_pass->damage_rect = gfx::Rect();
-    SubmitPassListAsFrame(child_support_.get(), child_local_surface_id,
-                          &child_pass_list);
-  }
-
-  {
-    CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-    const RenderPassList& aggregated_pass_list =
-        aggregated_frame.render_pass_list;
-
-    // Output frame should have no damage, but all quads included.
-    ASSERT_EQ(3u, aggregated_pass_list.size());
-
-    EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[0]->damage_rect);
-    EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[1]->damage_rect);
-    EXPECT_TRUE(aggregated_pass_list[2]->damage_rect.IsEmpty());
-    ASSERT_EQ(1u, aggregated_pass_list[0]->quad_list.size());
-    ASSERT_EQ(1u, aggregated_pass_list[1]->quad_list.size());
-    EXPECT_EQ(gfx::Rect(1, 1, 2, 2),
-              aggregated_pass_list[0]->quad_list.ElementAt(0)->visible_rect);
-    EXPECT_EQ(gfx::Rect(0, 0, 2, 2),
-              aggregated_pass_list[1]->quad_list.ElementAt(0)->visible_rect);
-    ASSERT_EQ(1u, aggregated_pass_list[2]->quad_list.size());
-  }
-
-  {
-    CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-    const RenderPassList& aggregated_pass_list =
-        aggregated_frame.render_pass_list;
-    // There were no changes since last aggregation, so output should be empty
-    // and have no damage.
-    ASSERT_EQ(1u, aggregated_pass_list.size());
-    EXPECT_TRUE(aggregated_pass_list[0]->damage_rect.IsEmpty());
-    ASSERT_EQ(0u, aggregated_pass_list[0]->quad_list.size());
-  }
-
-  // Root surface has smaller damage rect, but filter on render pass means all
-  // of it and its descendant passes should be aggregated.
-  {
-    int root_pass_ids[] = {1, 2, 3};
-    test::Quad root_quads1[] = {
-        test::Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
-    test::Quad root_quads2[] = {test::Quad::RenderPassQuad(root_pass_ids[0])};
-    test::Quad root_quads3[] = {test::Quad::RenderPassQuad(root_pass_ids[1])};
-    test::Pass root_passes[] = {
-        test::Pass(root_quads1, arraysize(root_quads1), root_pass_ids[0]),
-        test::Pass(root_quads2, arraysize(root_quads2), root_pass_ids[1]),
-        test::Pass(root_quads3, arraysize(root_quads3), root_pass_ids[2])};
-
-    RenderPassList root_pass_list;
-    AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes,
-              arraysize(root_passes));
-
-    RenderPass* filter_pass = root_pass_list[1].get();
-    filter_pass->shared_quad_state_list.front()
-        ->quad_to_target_transform.Translate(10, 10);
-    RenderPass* root_pass = root_pass_list[2].get();
-    filter_pass->filters.Append(FilterOperation::CreateBlurFilter(2));
-    root_pass->damage_rect = gfx::Rect(10, 10, 2, 2);
-    SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
-                          &root_pass_list);
-  }
-
-  {
-    CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-    const RenderPassList& aggregated_pass_list =
-        aggregated_frame.render_pass_list;
-
-    ASSERT_EQ(4u, aggregated_pass_list.size());
-
-    EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[0]->damage_rect);
-    EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[1]->damage_rect);
-    EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[2]->damage_rect);
-    EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[3]->damage_rect);
-    EXPECT_EQ(1u, aggregated_pass_list[0]->quad_list.size());
-    EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size());
-    EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size());
-    // First render pass draw quad is outside damage rect, so shouldn't be
-    // drawn.
-    EXPECT_EQ(0u, aggregated_pass_list[3]->quad_list.size());
-  }
-
-  // Root surface has smaller damage rect. Background filter on render pass
-  // means Surface
-  // quad under it should be aggregated.
-  {
-    int root_pass_ids[] = {1, 2};
-    test::Quad root_quads1[] = {
-        test::Quad::SolidColorQuad(1),
-    };
-    test::Quad root_quads2[] = {
-        test::Quad::RenderPassQuad(root_pass_ids[0]),
-        test::Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
-    test::Pass root_passes[] = {
-        test::Pass(root_quads1, arraysize(root_quads1), root_pass_ids[0]),
-        test::Pass(root_quads2, arraysize(root_quads2), root_pass_ids[1])};
-
-    RenderPassList root_pass_list;
-    AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes,
-              arraysize(root_passes));
-
-    RenderPass* pass = root_pass_list[0].get();
-    RenderPass* root_pass = root_pass_list[1].get();
-    root_pass->shared_quad_state_list.ElementAt(1)
-        ->quad_to_target_transform.Translate(10, 10);
-    pass->background_filters.Append(FilterOperation::CreateBlurFilter(2));
-    root_pass->damage_rect = gfx::Rect(10, 10, 2, 2);
-    SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
-                          &root_pass_list);
-  }
-
-  {
-    CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
-
-    const RenderPassList& aggregated_pass_list =
-        aggregated_frame.render_pass_list;
-
-    ASSERT_EQ(3u, aggregated_pass_list.size());
-
-    // Pass 0 is solid color quad from root, but outside damage rect.
-    EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[0]->damage_rect);
-    EXPECT_EQ(0u, aggregated_pass_list[0]->quad_list.size());
-    EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[1]->damage_rect);
-    EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size());
-
-    // First render pass draw quad is outside damage rect, so shouldn't be
-    // drawn. SurfaceDrawQuad is after background filter, so corresponding
-    // RenderPassDrawQuad should be drawn.
-    EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[2]->damage_rect);
-    EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size());
-  }
-}
-
-class SurfaceAggregatorWithResourcesTest : public testing::Test {
- public:
-  void SetUp() override {
-    shared_bitmap_manager_.reset(new TestSharedBitmapManager);
-    resource_provider_ =
-        FakeResourceProvider::Create(nullptr, shared_bitmap_manager_.get());
-
-    aggregator_.reset(new SurfaceAggregator(manager_.surface_manager(),
-                                            resource_provider_.get(), false));
-    aggregator_->set_output_is_secure(true);
-  }
-
- protected:
-  FrameSinkManager manager_;
-  std::unique_ptr<viz::SharedBitmapManager> shared_bitmap_manager_;
-  std::unique_ptr<ResourceProvider> resource_provider_;
-  std::unique_ptr<SurfaceAggregator> aggregator_;
-};
-
-void SubmitCompositorFrameWithResources(ResourceId* resource_ids,
-                                        size_t num_resource_ids,
-                                        bool valid,
-                                        viz::SurfaceId child_id,
-                                        CompositorFrameSinkSupport* support,
-                                        viz::SurfaceId surface_id) {
-  CompositorFrame frame = test::MakeEmptyCompositorFrame();
-  std::unique_ptr<RenderPass> pass = RenderPass::Create();
-  pass->SetNew(1, gfx::Rect(0, 0, 20, 20), gfx::Rect(), gfx::Transform());
-  SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
-  sqs->opacity = 1.f;
-  if (child_id.is_valid()) {
-    SurfaceDrawQuad* surface_quad =
-        pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-    surface_quad->SetNew(sqs, gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1),
-                         child_id, SurfaceDrawQuadType::PRIMARY, nullptr);
-  }
-
-  for (size_t i = 0u; i < num_resource_ids; ++i) {
-    TransferableResource resource;
-    resource.id = resource_ids[i];
-    // ResourceProvider is software, so only software resources are valid.
-    resource.is_software = valid;
-    frame.resource_list.push_back(resource);
-    TextureDrawQuad* quad = pass->CreateAndAppendDrawQuad<TextureDrawQuad>();
-    const gfx::Rect rect;
-    const gfx::Rect opaque_rect;
-    const gfx::Rect visible_rect;
-    bool needs_blending = false;
-    bool premultiplied_alpha = false;
-    const gfx::PointF uv_top_left;
-    const gfx::PointF uv_bottom_right;
-    SkColor background_color = SK_ColorGREEN;
-    const float vertex_opacity[4] = {0.f, 0.f, 1.f, 1.f};
-    bool flipped = false;
-    bool nearest_neighbor = false;
-    bool secure_output_only = true;
-    quad->SetAll(sqs, rect, opaque_rect, visible_rect, needs_blending,
-                 resource_ids[i], gfx::Size(), premultiplied_alpha, uv_top_left,
-                 uv_bottom_right, background_color, vertex_opacity, flipped,
-                 nearest_neighbor, secure_output_only);
-  }
-  frame.render_pass_list.push_back(std::move(pass));
-  support->SubmitCompositorFrame(surface_id.local_surface_id(),
-                                 std::move(frame));
-}
-
-TEST_F(SurfaceAggregatorWithResourcesTest, TakeResourcesOneSurface) {
-  FakeCompositorFrameSinkSupportClient client;
-  std::unique_ptr<CompositorFrameSinkSupport> support =
-      CompositorFrameSinkSupport::Create(
-          &client, &manager_, kArbitraryRootFrameSinkId, kRootIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId local_surface_id(7u, base::UnguessableToken::Create());
-  viz::SurfaceId surface_id(support->frame_sink_id(), local_surface_id);
-
-  ResourceId ids[] = {11, 12, 13};
-  SubmitCompositorFrameWithResources(
-      ids, arraysize(ids), true, viz::SurfaceId(), support.get(), surface_id);
-
-  CompositorFrame frame = aggregator_->Aggregate(surface_id);
-
-  // Nothing should be available to be returned yet.
-  EXPECT_TRUE(client.returned_resources().empty());
-
-  SubmitCompositorFrameWithResources(NULL, 0u, true, viz::SurfaceId(),
-                                     support.get(), surface_id);
-
-  frame = aggregator_->Aggregate(surface_id);
-
-  ASSERT_EQ(3u, client.returned_resources().size());
-  ResourceId returned_ids[3];
-  for (size_t i = 0; i < 3; ++i) {
-    returned_ids[i] = client.returned_resources()[i].id;
-  }
-  EXPECT_THAT(returned_ids,
-              testing::WhenSorted(testing::ElementsAreArray(ids)));
-
-  support->EvictCurrentSurface();
-}
-
-// This test verifies that when a CompositorFrame is submitted to a new surface
-// ID, and a new display frame is generated, then the resources of the old
-// surface are returned to the appropriate client.
-TEST_F(SurfaceAggregatorWithResourcesTest, ReturnResourcesAsSurfacesChange) {
-  FakeCompositorFrameSinkSupportClient client;
-  std::unique_ptr<CompositorFrameSinkSupport> support =
-      CompositorFrameSinkSupport::Create(
-          &client, &manager_, kArbitraryRootFrameSinkId, kRootIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId local_surface_id1(7u, base::UnguessableToken::Create());
-  viz::LocalSurfaceId local_surface_id2(8u, base::UnguessableToken::Create());
-  viz::SurfaceId surface_id1(support->frame_sink_id(), local_surface_id1);
-  viz::SurfaceId surface_id2(support->frame_sink_id(), local_surface_id2);
-
-  ResourceId ids[] = {11, 12, 13};
-  SubmitCompositorFrameWithResources(
-      ids, arraysize(ids), true, viz::SurfaceId(), support.get(), surface_id1);
-
-  CompositorFrame frame = aggregator_->Aggregate(surface_id1);
-
-  // Nothing should be available to be returned yet.
-  EXPECT_TRUE(client.returned_resources().empty());
-
-  // Submitting a CompositorFrame to |surface_id2| should cause the surface
-  // associated with |surface_id1| to get garbage collected.
-  SubmitCompositorFrameWithResources(NULL, 0u, true, viz::SurfaceId(),
-                                     support.get(), surface_id2);
-
-  frame = aggregator_->Aggregate(surface_id2);
-
-  ASSERT_EQ(3u, client.returned_resources().size());
-  ResourceId returned_ids[3];
-  for (size_t i = 0; i < 3; ++i) {
-    returned_ids[i] = client.returned_resources()[i].id;
-  }
-  EXPECT_THAT(returned_ids,
-              testing::WhenSorted(testing::ElementsAreArray(ids)));
-
-  support->EvictCurrentSurface();
-}
-
-TEST_F(SurfaceAggregatorWithResourcesTest, TakeInvalidResources) {
-  FakeCompositorFrameSinkSupportClient client;
-  std::unique_ptr<CompositorFrameSinkSupport> support =
-      CompositorFrameSinkSupport::Create(
-          &client, &manager_, kArbitraryRootFrameSinkId, kRootIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId local_surface_id(7u, base::UnguessableToken::Create());
-  viz::SurfaceId surface_id(support->frame_sink_id(), local_surface_id);
-
-  CompositorFrame frame = test::MakeCompositorFrame();
-  TransferableResource resource;
-  resource.id = 11;
-  // ResourceProvider is software but resource is not, so it should be
-  // ignored.
-  resource.is_software = false;
-  frame.resource_list.push_back(resource);
-  support->SubmitCompositorFrame(local_surface_id, std::move(frame));
-
-  CompositorFrame returned_frame = aggregator_->Aggregate(surface_id);
-
-  // Nothing should be available to be returned yet.
-  EXPECT_TRUE(client.returned_resources().empty());
-
-  SubmitCompositorFrameWithResources(NULL, 0, true, viz::SurfaceId(),
-                                     support.get(), surface_id);
-  ASSERT_EQ(1u, client.returned_resources().size());
-  EXPECT_EQ(11u, client.returned_resources()[0].id);
-
-  support->EvictCurrentSurface();
-}
-
-TEST_F(SurfaceAggregatorWithResourcesTest, TwoSurfaces) {
-  FakeCompositorFrameSinkSupportClient client;
-  std::unique_ptr<CompositorFrameSinkSupport> support1 =
-      CompositorFrameSinkSupport::Create(
-          &client, &manager_, viz::FrameSinkId(1, 1), kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  std::unique_ptr<CompositorFrameSinkSupport> support2 =
-      CompositorFrameSinkSupport::Create(
-          &client, &manager_, viz::FrameSinkId(2, 2), kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId local_frame1_id(7u, base::UnguessableToken::Create());
-  viz::SurfaceId surface1_id(support1->frame_sink_id(), local_frame1_id);
-
-  viz::LocalSurfaceId local_frame2_id(8u, base::UnguessableToken::Create());
-  viz::SurfaceId surface2_id(support2->frame_sink_id(), local_frame2_id);
-
-  ResourceId ids[] = {11, 12, 13};
-  SubmitCompositorFrameWithResources(
-      ids, arraysize(ids), true, viz::SurfaceId(), support1.get(), surface1_id);
-  ResourceId ids2[] = {14, 15, 16};
-  SubmitCompositorFrameWithResources(ids2, arraysize(ids2), true,
-                                     viz::SurfaceId(), support2.get(),
-                                     surface2_id);
-
-  CompositorFrame frame = aggregator_->Aggregate(surface1_id);
-
-  SubmitCompositorFrameWithResources(NULL, 0, true, viz::SurfaceId(),
-                                     support1.get(), surface1_id);
-
-  // Nothing should be available to be returned yet.
-  EXPECT_TRUE(client.returned_resources().empty());
-
-  frame = aggregator_->Aggregate(surface2_id);
-
-  // surface1_id wasn't referenced, so its resources should be returned.
-  ASSERT_EQ(3u, client.returned_resources().size());
-  ResourceId returned_ids[3];
-  for (size_t i = 0; i < 3; ++i) {
-    returned_ids[i] = client.returned_resources()[i].id;
-  }
-  EXPECT_THAT(returned_ids,
-              testing::WhenSorted(testing::ElementsAreArray(ids)));
-  EXPECT_EQ(3u, resource_provider_->num_resources());
-
-  support1->EvictCurrentSurface();
-  support2->EvictCurrentSurface();
-}
-
-// Ensure that aggregator completely ignores Surfaces that reference invalid
-// resources.
-TEST_F(SurfaceAggregatorWithResourcesTest, InvalidChildSurface) {
-  std::unique_ptr<CompositorFrameSinkSupport> root_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryRootFrameSinkId, kRootIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  std::unique_ptr<CompositorFrameSinkSupport> middle_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryMiddleFrameSinkId, kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  std::unique_ptr<CompositorFrameSinkSupport> child_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId root_local_surface_id(7u, kArbitraryToken);
-  viz::SurfaceId root_surface_id(root_support->frame_sink_id(),
-                                 root_local_surface_id);
-  viz::LocalSurfaceId middle_local_surface_id(8u, kArbitraryToken);
-  viz::SurfaceId middle_surface_id(middle_support->frame_sink_id(),
-                                   middle_local_surface_id);
-  viz::LocalSurfaceId child_local_surface_id(9u, kArbitraryToken);
-  viz::SurfaceId child_surface_id(child_support->frame_sink_id(),
-                                  child_local_surface_id);
-
-  ResourceId ids[] = {14, 15, 16};
-  SubmitCompositorFrameWithResources(ids, arraysize(ids), true,
-                                     viz::SurfaceId(), child_support.get(),
-                                     child_surface_id);
-
-  ResourceId ids2[] = {17, 18, 19};
-  SubmitCompositorFrameWithResources(ids2, arraysize(ids2), false,
-                                     child_surface_id, middle_support.get(),
-                                     middle_surface_id);
-
-  ResourceId ids3[] = {20, 21, 22};
-  SubmitCompositorFrameWithResources(ids3, arraysize(ids3), true,
-                                     middle_surface_id, root_support.get(),
-                                     root_surface_id);
-
-  CompositorFrame frame;
-  frame = aggregator_->Aggregate(root_surface_id);
-
-  RenderPassList* pass_list = &frame.render_pass_list;
-  ASSERT_EQ(1u, pass_list->size());
-  EXPECT_EQ(1u, pass_list->back()->shared_quad_state_list.size());
-  EXPECT_EQ(3u, pass_list->back()->quad_list.size());
-  SubmitCompositorFrameWithResources(ids2, arraysize(ids), true,
-                                     child_surface_id, middle_support.get(),
-                                     middle_surface_id);
-
-  frame = aggregator_->Aggregate(root_surface_id);
-
-  pass_list = &frame.render_pass_list;
-  ASSERT_EQ(1u, pass_list->size());
-  EXPECT_EQ(3u, pass_list->back()->shared_quad_state_list.size());
-  EXPECT_EQ(9u, pass_list->back()->quad_list.size());
-
-  root_support->EvictCurrentSurface();
-  middle_support->EvictCurrentSurface();
-  child_support->EvictCurrentSurface();
-}
-
-TEST_F(SurfaceAggregatorWithResourcesTest, SecureOutputTexture) {
-  std::unique_ptr<CompositorFrameSinkSupport> support1 =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, viz::FrameSinkId(1, 1), kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  std::unique_ptr<CompositorFrameSinkSupport> support2 =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, viz::FrameSinkId(2, 2), kChildIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId local_frame1_id(7u, base::UnguessableToken::Create());
-  viz::SurfaceId surface1_id(support1->frame_sink_id(), local_frame1_id);
-
-  viz::LocalSurfaceId local_frame2_id(8u, base::UnguessableToken::Create());
-  viz::SurfaceId surface2_id(support2->frame_sink_id(), local_frame2_id);
-
-  ResourceId ids[] = {11, 12, 13};
-  SubmitCompositorFrameWithResources(
-      ids, arraysize(ids), true, viz::SurfaceId(), support1.get(), surface1_id);
-
-  CompositorFrame frame = aggregator_->Aggregate(surface1_id);
-
-  RenderPass* render_pass = frame.render_pass_list.back().get();
-
-  EXPECT_EQ(DrawQuad::TEXTURE_CONTENT, render_pass->quad_list.back()->material);
-
-  {
-    std::unique_ptr<RenderPass> pass = RenderPass::Create();
-    pass->SetNew(1, gfx::Rect(0, 0, 20, 20), gfx::Rect(), gfx::Transform());
-    SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState();
-    sqs->opacity = 1.f;
-    SurfaceDrawQuad* surface_quad =
-        pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-
-    surface_quad->SetNew(sqs, gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1),
-                         surface1_id, SurfaceDrawQuadType::PRIMARY, nullptr);
-    pass->copy_requests.push_back(CopyOutputRequest::CreateEmptyRequest());
-
-    CompositorFrame frame = test::MakeEmptyCompositorFrame();
-    frame.render_pass_list.push_back(std::move(pass));
-
-    support2->SubmitCompositorFrame(local_frame2_id, std::move(frame));
-  }
-
-  frame = aggregator_->Aggregate(surface2_id);
-  EXPECT_EQ(1u, frame.render_pass_list.size());
-  render_pass = frame.render_pass_list.front().get();
-
-  // Parent has copy request, so texture should not be drawn.
-  EXPECT_EQ(DrawQuad::SOLID_COLOR, render_pass->quad_list.back()->material);
-
-  frame = aggregator_->Aggregate(surface2_id);
-  EXPECT_EQ(1u, frame.render_pass_list.size());
-  render_pass = frame.render_pass_list.front().get();
-
-  // Copy request has been executed earlier, so texture should be drawn.
-  EXPECT_EQ(DrawQuad::TEXTURE_CONTENT,
-            render_pass->quad_list.front()->material);
-
-  aggregator_->set_output_is_secure(false);
-
-  frame = aggregator_->Aggregate(surface2_id);
-  render_pass = frame.render_pass_list.back().get();
-
-  // Output is insecure, so texture should be drawn.
-  EXPECT_EQ(DrawQuad::SOLID_COLOR, render_pass->quad_list.back()->material);
-
-  support1->EvictCurrentSurface();
-  support2->EvictCurrentSurface();
-}
-
-// Ensure that the render passes have correct color spaces.
-TEST_F(SurfaceAggregatorValidSurfaceTest, ColorSpaceTest) {
-  test::Quad quads[][2] = {{test::Quad::SolidColorQuad(SK_ColorWHITE),
-                            test::Quad::SolidColorQuad(SK_ColorLTGRAY)},
-                           {test::Quad::SolidColorQuad(SK_ColorGRAY),
-                            test::Quad::SolidColorQuad(SK_ColorDKGRAY)}};
-  test::Pass passes[] = {test::Pass(quads[0], arraysize(quads[0]), 2),
-                         test::Pass(quads[1], arraysize(quads[1]), 1)};
-  gfx::ColorSpace color_space1 = gfx::ColorSpace::CreateXYZD50();
-  gfx::ColorSpace color_space2 = gfx::ColorSpace::CreateSRGB();
-  gfx::ColorSpace color_space3 = gfx::ColorSpace::CreateSCRGBLinear();
-
-  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
-                        root_local_surface_id_);
-
-  viz::SurfaceId surface_id(support_->frame_sink_id(), root_local_surface_id_);
-
-  CompositorFrame aggregated_frame;
-  aggregator_.SetOutputColorSpace(color_space1, color_space1);
-  aggregated_frame = aggregator_.Aggregate(surface_id);
-  EXPECT_EQ(2u, aggregated_frame.render_pass_list.size());
-  EXPECT_EQ(color_space1, aggregated_frame.render_pass_list[0]->color_space);
-  EXPECT_EQ(color_space1, aggregated_frame.render_pass_list[1]->color_space);
-
-  aggregator_.SetOutputColorSpace(color_space2, color_space2);
-  aggregated_frame = aggregator_.Aggregate(surface_id);
-  EXPECT_EQ(2u, aggregated_frame.render_pass_list.size());
-  EXPECT_EQ(color_space2, aggregated_frame.render_pass_list[0]->color_space);
-  EXPECT_EQ(color_space2, aggregated_frame.render_pass_list[1]->color_space);
-
-  aggregator_.SetOutputColorSpace(color_space1, color_space3);
-  aggregated_frame = aggregator_.Aggregate(surface_id);
-  EXPECT_EQ(3u, aggregated_frame.render_pass_list.size());
-  EXPECT_EQ(color_space1, aggregated_frame.render_pass_list[0]->color_space);
-  EXPECT_EQ(color_space1, aggregated_frame.render_pass_list[1]->color_space);
-  EXPECT_EQ(color_space3, aggregated_frame.render_pass_list[2]->color_space);
-}
-
-}  // namespace
-}  // namespace cc
-
diff --git a/cc/surfaces/surface_hittest_unittest.cc b/cc/surfaces/surface_hittest_unittest.cc
index 4f3ddfe..3a87fe8 100644
--- a/cc/surfaces/surface_hittest_unittest.cc
+++ b/cc/surfaces/surface_hittest_unittest.cc
@@ -5,7 +5,6 @@
 #include <stddef.h>
 
 #include "cc/output/compositor_frame.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
 #include "cc/surfaces/frame_sink_manager.h"
 #include "cc/surfaces/surface.h"
 #include "cc/surfaces/surface_hittest.h"
@@ -13,6 +12,7 @@
 #include "cc/test/compositor_frame_helpers.h"
 #include "cc/test/surface_hittest_test_helpers.h"
 #include "components/viz/common/local_surface_id_allocator.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/gfx/geometry/size.h"
@@ -68,10 +68,9 @@
 TEST(SurfaceHittestTest, Hittest_BadCompositorFrameDoesNotCrash) {
   FrameSinkManager manager;
   viz::FrameSinkId root_frame_sink_id(kArbitraryFrameSinkId);
-  std::unique_ptr<CompositorFrameSinkSupport> root_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager, kArbitraryFrameSinkId, kIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto root_support = viz::CompositorFrameSinkSupport::Create(
+      nullptr, &manager, kArbitraryFrameSinkId, kIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
 
   // Creates a root surface.
   gfx::Rect root_rect(300, 300);
@@ -113,10 +112,9 @@
 
   // Set up root FrameSink.
   viz::FrameSinkId root_frame_sink_id(1, 1);
-  std::unique_ptr<CompositorFrameSinkSupport> root_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager, root_frame_sink_id, kIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto root_support = viz::CompositorFrameSinkSupport::Create(
+      nullptr, &manager, root_frame_sink_id, kIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
 
   // Creates a root surface.
   gfx::Rect root_rect(300, 300);
@@ -148,17 +146,15 @@
 
   // Set up root FrameSink.
   viz::FrameSinkId root_frame_sink_id(1, 1);
-  std::unique_ptr<CompositorFrameSinkSupport> root_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager, root_frame_sink_id, kIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto root_support = viz::CompositorFrameSinkSupport::Create(
+      nullptr, &manager, root_frame_sink_id, kIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
 
   // Set up child FrameSink.
   viz::FrameSinkId child_frame_sink_id(2, 2);
-  std::unique_ptr<CompositorFrameSinkSupport> child_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager, child_frame_sink_id, kIsChildRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto child_support = viz::CompositorFrameSinkSupport::Create(
+      nullptr, &manager, child_frame_sink_id, kIsChildRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
 
   // Creates a root surface.
   gfx::Rect root_rect(300, 300);
@@ -291,17 +287,15 @@
 
   // Set up root FrameSink.
   viz::FrameSinkId root_frame_sink_id(1, 1);
-  std::unique_ptr<CompositorFrameSinkSupport> root_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager, root_frame_sink_id, kIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto root_support = viz::CompositorFrameSinkSupport::Create(
+      nullptr, &manager, root_frame_sink_id, kIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
 
   // Set up child FrameSink.
   viz::FrameSinkId child_frame_sink_id(2, 2);
-  std::unique_ptr<CompositorFrameSinkSupport> child_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager, child_frame_sink_id, kIsChildRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto child_support = viz::CompositorFrameSinkSupport::Create(
+      nullptr, &manager, child_frame_sink_id, kIsChildRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
 
   // Creates a root surface.
   gfx::Rect root_rect(300, 300);
@@ -400,10 +394,9 @@
 TEST(SurfaceHittestTest, Hittest_RenderPassDrawQuad) {
   FrameSinkManager manager;
   viz::FrameSinkId root_frame_sink_id(kArbitraryFrameSinkId);
-  std::unique_ptr<CompositorFrameSinkSupport> support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager, root_frame_sink_id, kIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto support = viz::CompositorFrameSinkSupport::Create(
+      nullptr, &manager, root_frame_sink_id, kIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
 
   // Create a CompostiorFrame with two RenderPasses.
   gfx::Rect root_rect(300, 300);
@@ -505,17 +498,15 @@
 
   // Set up root FrameSink.
   viz::FrameSinkId root_frame_sink_id(1, 1);
-  std::unique_ptr<CompositorFrameSinkSupport> root_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager, root_frame_sink_id, kIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto root_support = viz::CompositorFrameSinkSupport::Create(
+      nullptr, &manager, root_frame_sink_id, kIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
 
   // Set up child FrameSink.
   viz::FrameSinkId child_frame_sink_id(2, 2);
-  std::unique_ptr<CompositorFrameSinkSupport> child_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager, child_frame_sink_id, kIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto child_support = viz::CompositorFrameSinkSupport::Create(
+      nullptr, &manager, child_frame_sink_id, kIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
 
   // Creates a root surface.
   gfx::Rect root_rect(300, 300);
diff --git a/cc/surfaces/surface_manager_ref_unittest.cc b/cc/surfaces/surface_manager_ref_unittest.cc
index 88977da..075012f 100644
--- a/cc/surfaces/surface_manager_ref_unittest.cc
+++ b/cc/surfaces/surface_manager_ref_unittest.cc
@@ -9,12 +9,12 @@
 
 #include "base/containers/flat_set.h"
 #include "base/memory/ptr_util.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
 #include "cc/surfaces/frame_sink_manager.h"
 #include "cc/surfaces/surface.h"
 #include "cc/surfaces/surface_manager.h"
 #include "cc/test/compositor_frame_helpers.h"
 #include "components/viz/common/surface_id.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -54,14 +54,14 @@
         .EvictCurrentSurface();
   }
 
-  CompositorFrameSinkSupport& GetCompositorFrameSinkSupport(
+  viz::CompositorFrameSinkSupport& GetCompositorFrameSinkSupport(
       const viz::FrameSinkId& frame_sink_id) {
     auto& support_ptr = supports_[frame_sink_id];
     if (!support_ptr) {
       constexpr bool is_root = false;
       constexpr bool handles_frame_sink_id_invalidation = true;
       constexpr bool needs_sync_points = true;
-      support_ptr = CompositorFrameSinkSupport::Create(
+      support_ptr = viz::CompositorFrameSinkSupport::Create(
           nullptr, manager_.get(), frame_sink_id, is_root,
           handles_frame_sink_id_invalidation, needs_sync_points);
     }
@@ -123,7 +123,7 @@
   }
 
   std::unordered_map<viz::FrameSinkId,
-                     std::unique_ptr<CompositorFrameSinkSupport>,
+                     std::unique_ptr<viz::CompositorFrameSinkSupport>,
                      viz::FrameSinkIdHash>
       supports_;
   std::unique_ptr<FrameSinkManager> manager_;
diff --git a/cc/surfaces/surface_synchronization_unittest.cc b/cc/surfaces/surface_synchronization_unittest.cc
index f9aad93..546a737 100644
--- a/cc/surfaces/surface_synchronization_unittest.cc
+++ b/cc/surfaces/surface_synchronization_unittest.cc
@@ -3,7 +3,6 @@
 // found in the LICENSE file.
 
 #include "base/containers/flat_set.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
 #include "cc/surfaces/frame_sink_manager.h"
 #include "cc/test/begin_frame_args_test.h"
 #include "cc/test/compositor_frame_helpers.h"
@@ -11,6 +10,7 @@
 #include "cc/test/fake_surface_observer.h"
 #include "cc/test/mock_compositor_frame_sink_support_client.h"
 #include "components/viz/common/surface_id.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -75,27 +75,29 @@
         surface_observer_(false) {}
   ~SurfaceSynchronizationTest() override {}
 
-  CompositorFrameSinkSupport& display_support() { return *supports_[0]; }
+  viz::CompositorFrameSinkSupport& display_support() { return *supports_[0]; }
   Surface* display_surface() {
     return display_support().GetCurrentSurfaceForTesting();
   }
 
-  CompositorFrameSinkSupport& parent_support() { return *supports_[1]; }
+  viz::CompositorFrameSinkSupport& parent_support() { return *supports_[1]; }
   Surface* parent_surface() {
     return parent_support().GetCurrentSurfaceForTesting();
   }
 
-  CompositorFrameSinkSupport& child_support1() { return *supports_[2]; }
+  viz::CompositorFrameSinkSupport& child_support1() { return *supports_[2]; }
   Surface* child_surface1() {
     return child_support1().GetCurrentSurfaceForTesting();
   }
 
-  CompositorFrameSinkSupport& child_support2() { return *supports_[3]; }
+  viz::CompositorFrameSinkSupport& child_support2() { return *supports_[3]; }
   Surface* child_surface2() {
     return child_support2().GetCurrentSurfaceForTesting();
   }
 
-  CompositorFrameSinkSupport& support(int index) { return *supports_[index]; }
+  viz::CompositorFrameSinkSupport& support(int index) {
+    return *supports_[index];
+  }
   Surface* surface(int index) {
     return support(index).GetCurrentSurfaceForTesting();
   }
@@ -140,16 +142,16 @@
     begin_frame_source_->SetClient(&begin_frame_source_client_);
     now_src_ = base::MakeUnique<base::SimpleTestTickClock>();
     frame_sink_manager_.surface_manager()->AddObserver(&surface_observer_);
-    supports_.push_back(CompositorFrameSinkSupport::Create(
+    supports_.push_back(viz::CompositorFrameSinkSupport::Create(
         &support_client_, &frame_sink_manager_, kDisplayFrameSink, kIsRoot,
         kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints));
-    supports_.push_back(CompositorFrameSinkSupport::Create(
+    supports_.push_back(viz::CompositorFrameSinkSupport::Create(
         &support_client_, &frame_sink_manager_, kParentFrameSink, kIsChildRoot,
         kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints));
-    supports_.push_back(CompositorFrameSinkSupport::Create(
+    supports_.push_back(viz::CompositorFrameSinkSupport::Create(
         &support_client_, &frame_sink_manager_, kChildFrameSink1, kIsChildRoot,
         kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints));
-    supports_.push_back(CompositorFrameSinkSupport::Create(
+    supports_.push_back(viz::CompositorFrameSinkSupport::Create(
         &support_client_, &frame_sink_manager_, kChildFrameSink2, kIsChildRoot,
         kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints));
 
@@ -191,7 +193,7 @@
   FakeExternalBeginFrameSourceClient begin_frame_source_client_;
   std::unique_ptr<FakeExternalBeginFrameSource> begin_frame_source_;
   std::unique_ptr<base::SimpleTestTickClock> now_src_;
-  std::vector<std::unique_ptr<CompositorFrameSinkSupport>> supports_;
+  std::vector<std::unique_ptr<viz::CompositorFrameSinkSupport>> supports_;
 
   DISALLOW_COPY_AND_ASSIGN(SurfaceSynchronizationTest);
 };
diff --git a/cc/surfaces/surface_unittest.cc b/cc/surfaces/surface_unittest.cc
index 42439b9..82958dc 100644
--- a/cc/surfaces/surface_unittest.cc
+++ b/cc/surfaces/surface_unittest.cc
@@ -5,7 +5,6 @@
 #include "cc/surfaces/surface.h"
 #include "base/memory/ptr_util.h"
 #include "cc/output/copy_output_result.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
 #include "cc/surfaces/frame_sink_manager.h"
 #include "cc/surfaces/surface_dependency_tracker.h"
 #include "cc/test/begin_frame_args_test.h"
@@ -13,6 +12,7 @@
 #include "cc/test/fake_external_begin_frame_source.h"
 #include "cc/test/scheduler_test_common.h"
 #include "components/viz/common/local_surface_id_allocator.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/geometry/size.h"
 
@@ -27,10 +27,9 @@
 TEST(SurfaceTest, SurfaceLifetime) {
   FrameSinkManager frame_sink_manager;
   SurfaceManager* surface_manager = frame_sink_manager.surface_manager();
-  std::unique_ptr<CompositorFrameSinkSupport> support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &frame_sink_manager, kArbitraryFrameSinkId, kIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto support = viz::CompositorFrameSinkSupport::Create(
+      nullptr, &frame_sink_manager, kArbitraryFrameSinkId, kIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
 
   viz::LocalSurfaceId local_surface_id(6, base::UnguessableToken::Create());
   viz::SurfaceId surface_id(kArbitraryFrameSinkId, local_surface_id);
@@ -60,10 +59,9 @@
 TEST(SurfaceTest, CopyRequestLifetime) {
   FrameSinkManager frame_sink_manager;
   SurfaceManager* surface_manager = frame_sink_manager.surface_manager();
-  std::unique_ptr<CompositorFrameSinkSupport> support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &frame_sink_manager, kArbitraryFrameSinkId, kIsRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto support = viz::CompositorFrameSinkSupport::Create(
+      nullptr, &frame_sink_manager, kArbitraryFrameSinkId, kIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
 
   viz::LocalSurfaceId local_surface_id(6, base::UnguessableToken::Create());
   viz::SurfaceId surface_id(kArbitraryFrameSinkId, local_surface_id);
diff --git a/cc/surfaces/surfaces_pixeltest.cc b/cc/surfaces/surfaces_pixeltest.cc
deleted file mode 100644
index f002c9c6..0000000
--- a/cc/surfaces/surfaces_pixeltest.cc
+++ /dev/null
@@ -1,342 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/output/compositor_frame.h"
-#include "cc/quads/render_pass.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/surface_draw_quad.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
-#include "cc/surfaces/frame_sink_manager.h"
-#include "cc/surfaces/surface.h"
-#include "cc/surfaces/surface_aggregator.h"
-#include "cc/surfaces/surface_manager.h"
-#include "cc/test/compositor_frame_helpers.h"
-#include "cc/test/pixel_comparator.h"
-#include "cc/test/pixel_test.h"
-#include "components/viz/common/local_surface_id_allocator.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-#if !defined(OS_ANDROID)
-
-namespace cc {
-namespace {
-
-constexpr viz::FrameSinkId kArbitraryRootFrameSinkId(1, 1);
-constexpr viz::FrameSinkId kArbitraryChildFrameSinkId(2, 2);
-constexpr viz::FrameSinkId kArbitraryLeftFrameSinkId(3, 3);
-constexpr viz::FrameSinkId kArbitraryRightFrameSinkId(4, 4);
-constexpr bool kIsRoot = true;
-constexpr bool kIsChildRoot = false;
-constexpr bool kHandlesFrameSinkIdInvalidation = true;
-constexpr bool kNeedsSyncPoints = true;
-
-class SurfacesPixelTest : public RendererPixelTest<GLRenderer> {
- public:
-  SurfacesPixelTest()
-      : support_(
-            CompositorFrameSinkSupport::Create(nullptr,
-                                               &manager_,
-                                               kArbitraryRootFrameSinkId,
-                                               kIsRoot,
-                                               kHandlesFrameSinkIdInvalidation,
-                                               kNeedsSyncPoints)) {}
-  ~SurfacesPixelTest() override { support_->EvictCurrentSurface(); }
-
- protected:
-  FrameSinkManager manager_;
-  viz::LocalSurfaceIdAllocator allocator_;
-  std::unique_ptr<CompositorFrameSinkSupport> support_;
-};
-
-SharedQuadState* CreateAndAppendTestSharedQuadState(
-    RenderPass* render_pass,
-    const gfx::Transform& transform,
-    const gfx::Size& size) {
-  const gfx::Rect layer_rect = gfx::Rect(size);
-  const gfx::Rect visible_layer_rect = gfx::Rect(size);
-  const gfx::Rect clip_rect = gfx::Rect(size);
-  bool is_clipped = false;
-  float opacity = 1.f;
-  const SkBlendMode blend_mode = SkBlendMode::kSrcOver;
-  SharedQuadState* shared_state = render_pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(transform, layer_rect, visible_layer_rect, clip_rect,
-                       is_clipped, opacity, blend_mode, 0);
-  return shared_state;
-}
-
-// Draws a very simple frame with no surface references.
-TEST_F(SurfacesPixelTest, DrawSimpleFrame) {
-  gfx::Rect rect(device_viewport_size_);
-  int id = 1;
-  std::unique_ptr<RenderPass> pass = RenderPass::Create();
-  pass->SetNew(id, rect, rect, gfx::Transform());
-
-  CreateAndAppendTestSharedQuadState(
-      pass.get(), gfx::Transform(), device_viewport_size_);
-
-  SolidColorDrawQuad* color_quad =
-      pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-  bool force_anti_aliasing_off = false;
-  color_quad->SetNew(pass->shared_quad_state_list.back(),
-                     rect,
-                     rect,
-                     SK_ColorGREEN,
-                     force_anti_aliasing_off);
-
-  CompositorFrame root_frame = test::MakeCompositorFrame();
-  root_frame.render_pass_list.push_back(std::move(pass));
-
-  viz::LocalSurfaceId root_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id);
-  support_->SubmitCompositorFrame(root_local_surface_id, std::move(root_frame));
-
-  SurfaceAggregator aggregator(manager_.surface_manager(),
-                               resource_provider_.get(), true);
-  CompositorFrame aggregated_frame = aggregator.Aggregate(root_surface_id);
-
-  bool discard_alpha = false;
-  ExactPixelComparator pixel_comparator(discard_alpha);
-  RenderPassList* pass_list = &aggregated_frame.render_pass_list;
-  EXPECT_TRUE(RunPixelTest(pass_list,
-                           base::FilePath(FILE_PATH_LITERAL("green.png")),
-                           pixel_comparator));
-}
-
-// Draws a frame with simple surface embedding.
-TEST_F(SurfacesPixelTest, DrawSimpleAggregatedFrame) {
-  gfx::Size child_size(200, 100);
-  std::unique_ptr<CompositorFrameSinkSupport> child_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryChildFrameSinkId, kIsChildRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-
-  viz::LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId child_surface_id(child_support->frame_sink_id(),
-                                  child_local_surface_id);
-  viz::LocalSurfaceId root_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id);
-
-  {
-    gfx::Rect rect(device_viewport_size_);
-    int id = 1;
-    std::unique_ptr<RenderPass> pass = RenderPass::Create();
-    pass->SetNew(id, rect, rect, gfx::Transform());
-
-    CreateAndAppendTestSharedQuadState(
-        pass.get(), gfx::Transform(), device_viewport_size_);
-
-    SurfaceDrawQuad* surface_quad =
-        pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-    surface_quad->SetNew(pass->shared_quad_state_list.back(),
-                         gfx::Rect(child_size), gfx::Rect(child_size),
-                         child_surface_id, SurfaceDrawQuadType::PRIMARY,
-                         nullptr);
-
-    SolidColorDrawQuad* color_quad =
-        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    bool force_anti_aliasing_off = false;
-    color_quad->SetNew(pass->shared_quad_state_list.back(),
-                       rect,
-                       rect,
-                       SK_ColorYELLOW,
-                       force_anti_aliasing_off);
-
-    CompositorFrame root_frame = test::MakeCompositorFrame();
-    root_frame.render_pass_list.push_back(std::move(pass));
-
-    support_->SubmitCompositorFrame(root_local_surface_id,
-                                    std::move(root_frame));
-  }
-
-  {
-    gfx::Rect rect(child_size);
-    int id = 1;
-    std::unique_ptr<RenderPass> pass = RenderPass::Create();
-    pass->SetNew(id, rect, rect, gfx::Transform());
-
-    CreateAndAppendTestSharedQuadState(
-        pass.get(), gfx::Transform(), child_size);
-
-    SolidColorDrawQuad* color_quad =
-        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    bool force_anti_aliasing_off = false;
-    color_quad->SetNew(pass->shared_quad_state_list.back(),
-                       rect,
-                       rect,
-                       SK_ColorBLUE,
-                       force_anti_aliasing_off);
-
-    CompositorFrame child_frame = test::MakeCompositorFrame();
-    child_frame.render_pass_list.push_back(std::move(pass));
-
-    child_support->SubmitCompositorFrame(child_local_surface_id,
-                                         std::move(child_frame));
-  }
-
-  SurfaceAggregator aggregator(manager_.surface_manager(),
-                               resource_provider_.get(), true);
-  CompositorFrame aggregated_frame = aggregator.Aggregate(root_surface_id);
-
-  bool discard_alpha = false;
-  ExactPixelComparator pixel_comparator(discard_alpha);
-  RenderPassList* pass_list = &aggregated_frame.render_pass_list;
-  EXPECT_TRUE(RunPixelTest(pass_list,
-                           base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
-                           pixel_comparator));
-
-  child_support->EvictCurrentSurface();
-}
-
-// Tests a surface quad that has a non-identity transform into its pass.
-TEST_F(SurfacesPixelTest, DrawAggregatedFrameWithSurfaceTransforms) {
-  gfx::Size child_size(100, 200);
-  gfx::Size quad_size(100, 100);
-  // Structure:
-  // root (200x200) -> left_child (100x200 @ 0x0,
-  //                   right_child (100x200 @ 0x100)
-  //   left_child -> top_green_quad (100x100 @ 0x0),
-  //                 bottom_blue_quad (100x100 @ 0x100)
-  //   right_child -> top_blue_quad (100x100 @ 0x0),
-  //                  bottom_green_quad (100x100 @ 0x100)
-  std::unique_ptr<CompositorFrameSinkSupport> left_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryLeftFrameSinkId, kIsChildRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  std::unique_ptr<CompositorFrameSinkSupport> right_support =
-      CompositorFrameSinkSupport::Create(
-          nullptr, &manager_, kArbitraryRightFrameSinkId, kIsChildRoot,
-          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
-  viz::LocalSurfaceId left_child_local_id = allocator_.GenerateId();
-  viz::SurfaceId left_child_id(left_support->frame_sink_id(),
-                               left_child_local_id);
-  viz::LocalSurfaceId right_child_local_id = allocator_.GenerateId();
-  viz::SurfaceId right_child_id(right_support->frame_sink_id(),
-                                right_child_local_id);
-  viz::LocalSurfaceId root_local_surface_id = allocator_.GenerateId();
-  viz::SurfaceId root_surface_id(support_->frame_sink_id(),
-                                 root_local_surface_id);
-
-  {
-    gfx::Rect rect(device_viewport_size_);
-    int id = 1;
-    std::unique_ptr<RenderPass> pass = RenderPass::Create();
-    pass->SetNew(id, rect, rect, gfx::Transform());
-
-    gfx::Transform surface_transform;
-    CreateAndAppendTestSharedQuadState(
-        pass.get(), surface_transform, device_viewport_size_);
-
-    SurfaceDrawQuad* left_surface_quad =
-        pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-    left_surface_quad->SetNew(pass->shared_quad_state_list.back(),
-                              gfx::Rect(child_size), gfx::Rect(child_size),
-                              left_child_id, SurfaceDrawQuadType::PRIMARY,
-                              nullptr);
-
-    surface_transform.Translate(100, 0);
-    CreateAndAppendTestSharedQuadState(
-        pass.get(), surface_transform, device_viewport_size_);
-
-    SurfaceDrawQuad* right_surface_quad =
-        pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-    right_surface_quad->SetNew(pass->shared_quad_state_list.back(),
-                               gfx::Rect(child_size), gfx::Rect(child_size),
-                               right_child_id, SurfaceDrawQuadType::PRIMARY,
-                               nullptr);
-
-    CompositorFrame root_frame = test::MakeCompositorFrame();
-    root_frame.render_pass_list.push_back(std::move(pass));
-
-    support_->SubmitCompositorFrame(root_local_surface_id,
-                                    std::move(root_frame));
-  }
-
-  {
-    gfx::Rect rect(child_size);
-    int id = 1;
-    std::unique_ptr<RenderPass> pass = RenderPass::Create();
-    pass->SetNew(id, rect, rect, gfx::Transform());
-
-    CreateAndAppendTestSharedQuadState(
-        pass.get(), gfx::Transform(), child_size);
-
-    SolidColorDrawQuad* top_color_quad =
-        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    bool force_anti_aliasing_off = false;
-    top_color_quad->SetNew(pass->shared_quad_state_list.back(),
-                           gfx::Rect(quad_size),
-                           gfx::Rect(quad_size),
-                           SK_ColorGREEN,
-                           force_anti_aliasing_off);
-
-    SolidColorDrawQuad* bottom_color_quad =
-        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    bottom_color_quad->SetNew(pass->shared_quad_state_list.back(),
-                              gfx::Rect(0, 100, 100, 100),
-                              gfx::Rect(0, 100, 100, 100),
-                              SK_ColorBLUE,
-                              force_anti_aliasing_off);
-
-    CompositorFrame child_frame = test::MakeCompositorFrame();
-    child_frame.render_pass_list.push_back(std::move(pass));
-
-    left_support->SubmitCompositorFrame(left_child_local_id,
-                                        std::move(child_frame));
-  }
-
-  {
-    gfx::Rect rect(child_size);
-    int id = 1;
-    std::unique_ptr<RenderPass> pass = RenderPass::Create();
-    pass->SetNew(id, rect, rect, gfx::Transform());
-
-    CreateAndAppendTestSharedQuadState(
-        pass.get(), gfx::Transform(), child_size);
-
-    SolidColorDrawQuad* top_color_quad =
-        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    bool force_anti_aliasing_off = false;
-    top_color_quad->SetNew(pass->shared_quad_state_list.back(),
-                           gfx::Rect(quad_size),
-                           gfx::Rect(quad_size),
-                           SK_ColorBLUE,
-                           force_anti_aliasing_off);
-
-    SolidColorDrawQuad* bottom_color_quad =
-        pass->CreateAndAppendDrawQuad<SolidColorDrawQuad>();
-    bottom_color_quad->SetNew(pass->shared_quad_state_list.back(),
-                              gfx::Rect(0, 100, 100, 100),
-                              gfx::Rect(0, 100, 100, 100),
-                              SK_ColorGREEN,
-                              force_anti_aliasing_off);
-
-    CompositorFrame child_frame = test::MakeCompositorFrame();
-    child_frame.render_pass_list.push_back(std::move(pass));
-
-    right_support->SubmitCompositorFrame(right_child_local_id,
-                                         std::move(child_frame));
-  }
-
-  SurfaceAggregator aggregator(manager_.surface_manager(),
-                               resource_provider_.get(), true);
-  CompositorFrame aggregated_frame = aggregator.Aggregate(root_surface_id);
-
-  bool discard_alpha = false;
-  ExactPixelComparator pixel_comparator(discard_alpha);
-  RenderPassList* pass_list = &aggregated_frame.render_pass_list;
-  EXPECT_TRUE(RunPixelTest(
-      pass_list,
-      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
-      pixel_comparator));
-
-  left_support->EvictCurrentSurface();
-  right_support->EvictCurrentSurface();
-}
-
-}  // namespace
-}  // namespace cc
-
-#endif  // !defined(OS_ANDROID)
diff --git a/cc/test/DEPS b/cc/test/DEPS
index 13ff54e..fffeee2 100644
--- a/cc/test/DEPS
+++ b/cc/test/DEPS
@@ -1,5 +1,7 @@
 include_rules = [
   "+components/viz/common",
+  "+components/viz/test",
+  "+components/viz/service",
   "+gpu/command_buffer/client/gl_in_process_context.h",
   "+gpu/command_buffer/client/gles2_implementation.h",
   "+gpu/command_buffer/client/gles2_interface_stub.h",
diff --git a/cc/test/cc_test_suite.cc b/cc/test/cc_test_suite.cc
index 246330c..1d997c9 100644
--- a/cc/test/cc_test_suite.cc
+++ b/cc/test/cc_test_suite.cc
@@ -6,7 +6,7 @@
 
 #include "base/message_loop/message_loop.h"
 #include "base/threading/thread_id_name_manager.h"
-#include "cc/test/paths.h"
+#include "components/viz/test/paths.h"
 #include "ui/gl/test/gl_surface_test_support.h"
 
 namespace cc {
@@ -19,7 +19,7 @@
 void CCTestSuite::Initialize() {
   base::TestSuite::Initialize();
   gl::GLSurfaceTestSupport::InitializeOneOff();
-  CCPaths::RegisterPathProvider();
+  viz::Paths::RegisterPathProvider();
 
   message_loop_.reset(new base::MessageLoop);
 
diff --git a/cc/test/fake_compositor_frame_sink_support_client.h b/cc/test/fake_compositor_frame_sink_support_client.h
index 462b988..52af6e2 100644
--- a/cc/test/fake_compositor_frame_sink_support_client.h
+++ b/cc/test/fake_compositor_frame_sink_support_client.h
@@ -5,14 +5,14 @@
 #ifndef CC_TEST_FAKE_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_
 #define CC_TEST_FAKE_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_
 
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
 #include "components/viz/common/local_surface_id.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h"
 #include "ui/gfx/geometry/rect.h"
 
 namespace cc {
 
 class FakeCompositorFrameSinkSupportClient
-    : public CompositorFrameSinkSupportClient {
+    : public viz::CompositorFrameSinkSupportClient {
  public:
   FakeCompositorFrameSinkSupportClient();
   ~FakeCompositorFrameSinkSupportClient() override;
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc
index 029a2bcb..345d890 100644
--- a/cc/test/layer_tree_pixel_test.cc
+++ b/cc/test/layer_tree_pixel_test.cc
@@ -16,14 +16,14 @@
 #include "cc/output/copy_output_request.h"
 #include "cc/output/copy_output_result.h"
 #include "cc/output/software_output_device.h"
-#include "cc/test/paths.h"
 #include "cc/test/pixel_comparator.h"
 #include "cc/test/pixel_test_output_surface.h"
 #include "cc/test/pixel_test_utils.h"
 #include "cc/test/test_in_process_context_provider.h"
-#include "cc/test/test_layer_tree_frame_sink.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "components/viz/common/quads/texture_mailbox.h"
+#include "components/viz/test/paths.h"
+#include "components/viz/test/test_layer_tree_frame_sink.h"
 #include "gpu/command_buffer/client/gles2_implementation.h"
 #include "gpu/ipc/gl_in_process_context.h"
 
@@ -38,7 +38,7 @@
 
 LayerTreePixelTest::~LayerTreePixelTest() {}
 
-std::unique_ptr<TestLayerTreeFrameSink>
+std::unique_ptr<viz::TestLayerTreeFrameSink>
 LayerTreePixelTest::CreateLayerTreeFrameSink(
     const RendererSettings& renderer_settings,
     double refresh_rate,
@@ -55,11 +55,12 @@
   bool synchronous_composite =
       !HasImplThread() &&
       !layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
-  auto delegating_output_surface = base::MakeUnique<TestLayerTreeFrameSink>(
-      compositor_context_provider, std::move(worker_context_provider),
-      shared_bitmap_manager(), gpu_memory_buffer_manager(), RendererSettings(),
-      ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync,
-      refresh_rate);
+  auto delegating_output_surface =
+      base::MakeUnique<viz::TestLayerTreeFrameSink>(
+          compositor_context_provider, std::move(worker_context_provider),
+          shared_bitmap_manager(), gpu_memory_buffer_manager(),
+          RendererSettings(), ImplThreadTaskRunner(), synchronous_composite,
+          disable_display_vsync, refresh_rate);
   delegating_output_surface->SetEnlargePassTextureAmount(
       enlarge_texture_amount_);
   return delegating_output_surface;
@@ -109,7 +110,7 @@
 
 void LayerTreePixelTest::AfterTest() {
   base::FilePath test_data_dir;
-  EXPECT_TRUE(PathService::Get(CCPaths::DIR_TEST_DATA, &test_data_dir));
+  EXPECT_TRUE(PathService::Get(viz::Paths::DIR_TEST_DATA, &test_data_dir));
   base::FilePath ref_file_path = test_data_dir.Append(ref_file_);
 
   base::CommandLine* cmd = base::CommandLine::ForCurrentProcess();
diff --git a/cc/test/layer_tree_pixel_test.h b/cc/test/layer_tree_pixel_test.h
index b1a6b0216..4e15faf 100644
--- a/cc/test/layer_tree_pixel_test.h
+++ b/cc/test/layer_tree_pixel_test.h
@@ -39,7 +39,7 @@
   ~LayerTreePixelTest() override;
 
   // LayerTreeTest overrides.
-  std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+  std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
       const RendererSettings& renderer_settings,
       double refresh_rate,
       scoped_refptr<ContextProvider> compositor_context_provider,
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index 415aa14b..51131b2 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -24,7 +24,6 @@
 #include "cc/test/fake_layer_tree_host_client.h"
 #include "cc/test/fake_output_surface.h"
 #include "cc/test/test_context_provider.h"
-#include "cc/test/test_layer_tree_frame_sink.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "cc/trees/layer_tree_host_client.h"
 #include "cc/trees/layer_tree_host_impl.h"
@@ -34,6 +33,7 @@
 #include "cc/trees/proxy_main.h"
 #include "cc/trees/single_thread_proxy.h"
 #include "components/viz/common/resources/buffer_to_texture_target_map.h"
+#include "components/viz/test/test_layer_tree_frame_sink.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "ui/gfx/geometry/size_conversions.h"
 
@@ -467,12 +467,12 @@
 };
 
 class LayerTreeTestLayerTreeFrameSinkClient
-    : public TestLayerTreeFrameSinkClient {
+    : public viz::TestLayerTreeFrameSinkClient {
  public:
   explicit LayerTreeTestLayerTreeFrameSinkClient(TestHooks* hooks)
       : hooks_(hooks) {}
 
-  // TestLayerTreeFrameSinkClient implementation.
+  // viz::TestLayerTreeFrameSinkClient implementation.
   std::unique_ptr<OutputSurface> CreateDisplayOutputSurface(
       scoped_refptr<ContextProvider> compositor_context_provider) override {
     return hooks_->CreateDisplayOutputSurfaceOnThread(
@@ -874,7 +874,8 @@
   layer_tree_host_->SetLayerTreeFrameSink(std::move(layer_tree_frame_sink));
 }
 
-std::unique_ptr<TestLayerTreeFrameSink> LayerTreeTest::CreateLayerTreeFrameSink(
+std::unique_ptr<viz::TestLayerTreeFrameSink>
+LayerTreeTest::CreateLayerTreeFrameSink(
     const RendererSettings& renderer_settings,
     double refresh_rate,
     scoped_refptr<ContextProvider> compositor_context_provider,
@@ -883,7 +884,7 @@
   bool synchronous_composite =
       !HasImplThread() &&
       !layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
-  return base::MakeUnique<TestLayerTreeFrameSink>(
+  return base::MakeUnique<viz::TestLayerTreeFrameSink>(
       compositor_context_provider, std::move(worker_context_provider),
       shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings,
       impl_task_runner_, synchronous_composite, disable_display_vsync,
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h
index 8b521b7..92aeb44 100644
--- a/cc/test/layer_tree_test.h
+++ b/cc/test/layer_tree_test.h
@@ -16,6 +16,10 @@
 #include "cc/trees/layer_tree_host_impl.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
+namespace viz {
+class TestLayerTreeFrameSink;
+}
+
 namespace cc {
 
 class AnimationHost;
@@ -26,7 +30,6 @@
 class LayerTreeTestLayerTreeFrameSinkClient;
 class Proxy;
 class TestContextProvider;
-class TestLayerTreeFrameSink;
 class TestTaskGraphRunner;
 
 // Creates the virtual viewport layer hierarchy under the given root_layer.
@@ -138,7 +141,7 @@
   // Override this and call the base class to change what ContextProviders will
   // be used (such as for pixel tests). Or override it and create your own
   // TestLayerTreeFrameSink to control how it is created.
-  virtual std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+  virtual std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
       const RendererSettings& renderer_settings,
       double refresh_rate,
       scoped_refptr<ContextProvider> compositor_context_provider,
diff --git a/cc/test/mock_compositor_frame_sink_support_client.h b/cc/test/mock_compositor_frame_sink_support_client.h
index 6f59c4a..d9712fb0 100644
--- a/cc/test/mock_compositor_frame_sink_support_client.h
+++ b/cc/test/mock_compositor_frame_sink_support_client.h
@@ -5,14 +5,14 @@
 #ifndef CC_TEST_MOCK_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_
 #define CC_TEST_MOCK_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_
 
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace cc {
 namespace test {
 
 class MockCompositorFrameSinkSupportClient
-    : public CompositorFrameSinkSupportClient {
+    : public viz::CompositorFrameSinkSupportClient {
  public:
   MockCompositorFrameSinkSupportClient();
   ~MockCompositorFrameSinkSupportClient() override;
diff --git a/cc/test/paths.cc b/cc/test/paths.cc
deleted file mode 100644
index bcd324b6..0000000
--- a/cc/test/paths.cc
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/test/paths.h"
-
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/path_service.h"
-
-namespace cc {
-
-bool PathProvider(int key, base::FilePath* result) {
-  base::FilePath cur;
-  switch (key) {
-    // The following are only valid in the development environment, and
-    // will fail if executed from an installed executable (because the
-    // generated path won't exist).
-    case CCPaths::DIR_TEST_DATA:
-      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
-        return false;
-      cur = cur.Append(FILE_PATH_LITERAL("cc"));
-      cur = cur.Append(FILE_PATH_LITERAL("test"));
-      cur = cur.Append(FILE_PATH_LITERAL("data"));
-      if (!base::PathExists(cur))  // we don't want to create this
-        return false;
-      break;
-    default:
-      return false;
-  }
-
-  *result = cur;
-  return true;
-}
-
-// This cannot be done as a static initializer sadly since Visual Studio will
-// eliminate this object file if there is no direct entry point into it.
-void CCPaths::RegisterPathProvider() {
-  PathService::RegisterProvider(PathProvider, PATH_START, PATH_END);
-}
-
-}  // namespace cc
diff --git a/cc/test/paths.h b/cc/test/paths.h
deleted file mode 100644
index f48177e..0000000
--- a/cc/test/paths.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_TEST_PATHS_H_
-#define CC_TEST_PATHS_H_
-
-namespace cc {
-
-class CCPaths {
- public:
-  enum {
-    PATH_START = 5000,
-
-    // Valid only in development and testing environments.
-    DIR_TEST_DATA,
-    PATH_END
-  };
-
-  // Call once to register the provider for the path keys defined above.
-  static void RegisterPathProvider();
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_PATHS_H_
diff --git a/cc/test/pixel_test.cc b/cc/test/pixel_test.cc
index 401923d..9938446 100644
--- a/cc/test/pixel_test.cc
+++ b/cc/test/pixel_test.cc
@@ -22,13 +22,13 @@
 #include "cc/resources/resource_provider.h"
 #include "cc/scheduler/begin_frame_source.h"
 #include "cc/test/fake_output_surface_client.h"
-#include "cc/test/paths.h"
 #include "cc/test/pixel_test_output_surface.h"
 #include "cc/test/pixel_test_utils.h"
 #include "cc/test/test_gpu_memory_buffer_manager.h"
 #include "cc/test/test_in_process_context_provider.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "cc/trees/blocking_task_runner.h"
+#include "components/viz/test/paths.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -138,7 +138,7 @@
 bool PixelTest::PixelsMatchReference(const base::FilePath& ref_file,
                                      const PixelComparator& comparator) {
   base::FilePath test_data_dir;
-  if (!PathService::Get(CCPaths::DIR_TEST_DATA, &test_data_dir))
+  if (!PathService::Get(viz::Paths::DIR_TEST_DATA, &test_data_dir))
     return false;
 
   // If this is false, we didn't set up a readback on a render pass.
diff --git a/cc/test/surface_aggregator_test_helpers.cc b/cc/test/surface_aggregator_test_helpers.cc
deleted file mode 100644
index 4c17955..0000000
--- a/cc/test/surface_aggregator_test_helpers.cc
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/test/surface_aggregator_test_helpers.h"
-
-#include <stddef.h>
-
-#include "base/format_macros.h"
-#include "base/strings/stringprintf.h"
-#include "cc/layers/append_quads_data.h"
-#include "cc/output/compositor_frame.h"
-#include "cc/quads/render_pass_draw_quad.h"
-#include "cc/quads/shared_quad_state.h"
-#include "cc/quads/solid_color_draw_quad.h"
-#include "cc/quads/surface_draw_quad.h"
-#include "cc/surfaces/surface.h"
-#include "cc/test/render_pass_test_utils.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/skia/include/core/SkBlendMode.h"
-
-namespace cc {
-namespace test {
-
-void AddSurfaceQuad(RenderPass* pass,
-                    const gfx::Size& surface_size,
-                    float opacity,
-                    const viz::SurfaceId& primary_surface_id,
-                    const viz::SurfaceId& fallback_surface_id) {
-  gfx::Transform layer_to_target_transform;
-  gfx::Size layer_bounds = surface_size;
-  gfx::Rect visible_layer_rect = gfx::Rect(surface_size);
-  gfx::Rect clip_rect = gfx::Rect(surface_size);
-  bool is_clipped = false;
-  SkBlendMode blend_mode = SkBlendMode::kSrcOver;
-
-  SharedQuadState* shared_quad_state = pass->CreateAndAppendSharedQuadState();
-  shared_quad_state->SetAll(layer_to_target_transform, gfx::Rect(layer_bounds),
-                            visible_layer_rect, clip_rect, is_clipped, opacity,
-                            blend_mode, 0);
-
-  SurfaceDrawQuad* surface_quad =
-      pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-  SurfaceDrawQuad* fallback_surface_quad = nullptr;
-  if (fallback_surface_id.is_valid())
-    fallback_surface_quad = pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>();
-
-  gfx::Rect quad_rect = gfx::Rect(surface_size);
-  surface_quad->SetNew(pass->shared_quad_state_list.back(), quad_rect,
-                       quad_rect, primary_surface_id,
-                       SurfaceDrawQuadType::PRIMARY, fallback_surface_quad);
-
-  if (fallback_surface_quad) {
-    fallback_surface_quad->SetNew(pass->shared_quad_state_list.back(),
-                                  quad_rect, quad_rect, fallback_surface_id,
-                                  SurfaceDrawQuadType::FALLBACK, nullptr);
-  }
-}
-
-void AddRenderPassQuad(RenderPass* pass, RenderPassId render_pass_id) {
-  gfx::Rect output_rect = gfx::Rect(0, 0, 5, 5);
-  SharedQuadState* shared_state = pass->CreateAndAppendSharedQuadState();
-  shared_state->SetAll(gfx::Transform(), output_rect, output_rect, output_rect,
-                       false, 1, SkBlendMode::kSrcOver, 0);
-  RenderPassDrawQuad* quad =
-      pass->CreateAndAppendDrawQuad<RenderPassDrawQuad>();
-  quad->SetNew(shared_state, output_rect, output_rect, render_pass_id, 0,
-               gfx::RectF(), gfx::Size(), gfx::Vector2dF(), gfx::PointF(),
-               gfx::RectF());
-}
-
-void AddQuadInPass(RenderPass* pass, const Quad& desc) {
-  switch (desc.material) {
-    case DrawQuad::SOLID_COLOR:
-      AddQuad(pass, gfx::Rect(0, 0, 5, 5), desc.color);
-      break;
-    case DrawQuad::SURFACE_CONTENT:
-      AddSurfaceQuad(pass, gfx::Size(5, 5), desc.opacity,
-                     desc.primary_surface_id, desc.fallback_surface_id);
-      break;
-    case DrawQuad::RENDER_PASS:
-      AddRenderPassQuad(pass, desc.render_pass_id);
-      break;
-    default:
-      NOTREACHED();
-  }
-}
-
-void AddPasses(RenderPassList* pass_list,
-               const gfx::Rect& output_rect,
-               Pass* passes,
-               size_t pass_count) {
-  gfx::Transform root_transform;
-  for (size_t i = 0; i < pass_count; ++i) {
-    Pass pass = passes[i];
-    RenderPass* test_pass = AddRenderPass(pass_list, pass.id, output_rect,
-                                          root_transform, FilterOperations());
-    for (size_t j = 0; j < pass.quad_count; ++j) {
-      AddQuadInPass(test_pass, pass.quads[j]);
-    }
-  }
-}
-
-void TestQuadMatchesExpectations(Quad expected_quad, const DrawQuad* quad) {
-  switch (expected_quad.material) {
-    case DrawQuad::SOLID_COLOR: {
-      ASSERT_EQ(DrawQuad::SOLID_COLOR, quad->material);
-
-      const SolidColorDrawQuad* solid_color_quad =
-          SolidColorDrawQuad::MaterialCast(quad);
-
-      EXPECT_EQ(expected_quad.color, solid_color_quad->color);
-      break;
-    }
-    case DrawQuad::RENDER_PASS: {
-      ASSERT_EQ(DrawQuad::RENDER_PASS, quad->material);
-
-      const RenderPassDrawQuad* render_pass_quad =
-          RenderPassDrawQuad::MaterialCast(quad);
-
-      EXPECT_EQ(expected_quad.render_pass_id, render_pass_quad->render_pass_id);
-      break;
-    }
-    default:
-      NOTREACHED();
-      break;
-  }
-}
-
-void TestPassMatchesExpectations(Pass expected_pass, const RenderPass* pass) {
-  ASSERT_EQ(expected_pass.quad_count, pass->quad_list.size());
-  for (auto iter = pass->quad_list.cbegin(); iter != pass->quad_list.cend();
-       ++iter) {
-    SCOPED_TRACE(base::StringPrintf("Quad number %" PRIuS, iter.index()));
-    TestQuadMatchesExpectations(expected_pass.quads[iter.index()], *iter);
-  }
-}
-
-void TestPassesMatchExpectations(Pass* expected_passes,
-                                 size_t expected_pass_count,
-                                 const RenderPassList* passes) {
-  ASSERT_EQ(expected_pass_count, passes->size());
-
-  for (size_t i = 0; i < passes->size(); ++i) {
-    SCOPED_TRACE(base::StringPrintf("Pass number %" PRIuS, i));
-    RenderPass* pass = (*passes)[i].get();
-    TestPassMatchesExpectations(expected_passes[i], pass);
-  }
-}
-
-}  // namespace test
-}  // namespace cc
diff --git a/cc/test/surface_aggregator_test_helpers.h b/cc/test/surface_aggregator_test_helpers.h
deleted file mode 100644
index cae3f03d..0000000
--- a/cc/test/surface_aggregator_test_helpers.h
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_TEST_SURFACE_AGGREGATOR_TEST_HELPERS_H_
-#define CC_TEST_SURFACE_AGGREGATOR_TEST_HELPERS_H_
-
-#include <stddef.h>
-
-#include <vector>
-
-#include "cc/quads/draw_quad.h"
-#include "cc/quads/render_pass.h"
-#include "components/viz/common/surface_id.h"
-#include "third_party/skia/include/core/SkColor.h"
-#include "ui/gfx/geometry/size.h"
-
-namespace cc {
-
-class RenderPass;
-class TestRenderPass;
-
-typedef std::vector<std::unique_ptr<RenderPass>> RenderPassList;
-
-namespace test {
-
-struct Quad {
-  static Quad SolidColorQuad(SkColor color) {
-    Quad quad;
-    quad.material = DrawQuad::SOLID_COLOR;
-    quad.color = color;
-    return quad;
-  }
-
-  static Quad SurfaceQuad(const viz::SurfaceId& primary_surface_id,
-                          const viz::SurfaceId& fallback_surface_id,
-                          float opacity) {
-    Quad quad;
-    quad.material = DrawQuad::SURFACE_CONTENT;
-    quad.opacity = opacity;
-    quad.primary_surface_id = primary_surface_id;
-    quad.fallback_surface_id = fallback_surface_id;
-    return quad;
-  }
-
-  static Quad RenderPassQuad(int id) {
-    Quad quad;
-    quad.material = DrawQuad::RENDER_PASS;
-    quad.render_pass_id = id;
-    return quad;
-  }
-
-  DrawQuad::Material material;
-  // Set when material==DrawQuad::SURFACE_CONTENT.
-  viz::SurfaceId primary_surface_id;
-  viz::SurfaceId fallback_surface_id;
-  float opacity;
-  // Set when material==DrawQuad::SOLID_COLOR.
-  SkColor color;
-  // Set when material==DrawQuad::RENDER_PASS.
-  RenderPassId render_pass_id;
-
- private:
-  Quad() : material(DrawQuad::INVALID), opacity(1.f), color(SK_ColorWHITE) {}
-};
-
-struct Pass {
-  Pass(Quad* quads, size_t quad_count, int id)
-      : quads(quads), quad_count(quad_count), id(id) {}
-  Pass(Quad* quads, size_t quad_count) : quads(quads), quad_count(quad_count) {}
-
-  Quad* quads;
-  size_t quad_count;
-  int id = 1;
-};
-
-void AddQuadInPass(TestRenderPass* pass, Quad desc);
-
-void AddPasses(RenderPassList* pass_list,
-               const gfx::Rect& output_rect,
-               Pass* passes,
-               size_t pass_count);
-
-void TestQuadMatchesExpectations(Quad expected_quad, const DrawQuad* quad);
-
-void TestPassMatchesExpectations(Pass expected_pass, const RenderPass* pass);
-
-void TestPassesMatchExpectations(Pass* expected_passes,
-                                 size_t expected_pass_count,
-                                 const RenderPassList* passes);
-
-}  // namespace test
-}  // namespace cc
-
-#endif  // CC_TEST_SURFACE_AGGREGATOR_TEST_HELPERS_H_
diff --git a/cc/test/test_layer_tree_frame_sink.cc b/cc/test/test_layer_tree_frame_sink.cc
deleted file mode 100644
index 246e84d..0000000
--- a/cc/test/test_layer_tree_frame_sink.cc
+++ /dev/null
@@ -1,222 +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/test/test_layer_tree_frame_sink.h"
-
-#include <stdint.h>
-#include <utility>
-
-#include "base/memory/ptr_util.h"
-#include "base/single_thread_task_runner.h"
-#include "cc/output/begin_frame_args.h"
-#include "cc/output/copy_output_request.h"
-#include "cc/output/direct_renderer.h"
-#include "cc/output/layer_tree_frame_sink_client.h"
-#include "cc/output/output_surface.h"
-#include "cc/output/texture_mailbox_deleter.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
-
-namespace cc {
-
-static constexpr viz::FrameSinkId kLayerTreeFrameSinkId(1, 1);
-
-TestLayerTreeFrameSink::TestLayerTreeFrameSink(
-    scoped_refptr<ContextProvider> compositor_context_provider,
-    scoped_refptr<ContextProvider> worker_context_provider,
-    viz::SharedBitmapManager* shared_bitmap_manager,
-    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-    const RendererSettings& renderer_settings,
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-    bool synchronous_composite,
-    bool disable_display_vsync,
-    double refresh_rate)
-    : LayerTreeFrameSink(std::move(compositor_context_provider),
-                         std::move(worker_context_provider),
-                         gpu_memory_buffer_manager,
-                         shared_bitmap_manager),
-      synchronous_composite_(synchronous_composite),
-      disable_display_vsync_(disable_display_vsync),
-      renderer_settings_(renderer_settings),
-      refresh_rate_(refresh_rate),
-      task_runner_(std::move(task_runner)),
-      frame_sink_id_(kLayerTreeFrameSinkId),
-      frame_sink_manager_(new FrameSinkManager),
-      local_surface_id_allocator_(new viz::LocalSurfaceIdAllocator),
-      external_begin_frame_source_(this),
-      weak_ptr_factory_(this) {
-  // Always use sync tokens so that code paths in resource provider that deal
-  // with sync tokens are tested.
-  capabilities_.delegated_sync_points_required = true;
-}
-
-TestLayerTreeFrameSink::~TestLayerTreeFrameSink() {
-  DCHECK(copy_requests_.empty());
-}
-
-void TestLayerTreeFrameSink::RequestCopyOfOutput(
-    std::unique_ptr<CopyOutputRequest> request) {
-  copy_requests_.push_back(std::move(request));
-}
-
-bool TestLayerTreeFrameSink::BindToClient(LayerTreeFrameSinkClient* client) {
-  if (!LayerTreeFrameSink::BindToClient(client))
-    return false;
-
-  std::unique_ptr<OutputSurface> display_output_surface =
-      test_client_->CreateDisplayOutputSurface(context_provider());
-  bool display_context_shared_with_compositor =
-      display_output_surface->context_provider() == context_provider();
-
-  std::unique_ptr<DisplayScheduler> scheduler;
-  if (!synchronous_composite_) {
-    if (disable_display_vsync_) {
-      begin_frame_source_.reset(new BackToBackBeginFrameSource(
-          base::MakeUnique<DelayBasedTimeSource>(task_runner_.get())));
-    } else {
-      begin_frame_source_.reset(new DelayBasedBeginFrameSource(
-          base::MakeUnique<DelayBasedTimeSource>(task_runner_.get())));
-      begin_frame_source_->SetAuthoritativeVSyncInterval(
-          base::TimeDelta::FromMilliseconds(1000.f / refresh_rate_));
-    }
-    scheduler.reset(new DisplayScheduler(
-        begin_frame_source_.get(), task_runner_.get(),
-        display_output_surface->capabilities().max_frames_pending));
-  }
-
-  display_ = base::MakeUnique<Display>(
-      shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings_,
-      frame_sink_id_, std::move(display_output_surface), std::move(scheduler),
-      base::MakeUnique<TextureMailboxDeleter>(task_runner_.get()));
-
-  // We want the Display's OutputSurface to hear about lost context, and when
-  // this shares a context with it we should not be listening for lost context
-  // callbacks on the context here.
-  if (display_context_shared_with_compositor && context_provider())
-    context_provider()->SetLostContextCallback(base::Closure());
-
-  constexpr bool is_root = false;
-  constexpr bool handles_frame_sink_id_invalidation = true;
-  constexpr bool needs_sync_points = true;
-  support_ = CompositorFrameSinkSupport::Create(
-      this, frame_sink_manager_.get(), frame_sink_id_, is_root,
-      handles_frame_sink_id_invalidation, needs_sync_points);
-  client_->SetBeginFrameSource(&external_begin_frame_source_);
-  if (begin_frame_source_) {
-    frame_sink_manager_->RegisterBeginFrameSource(begin_frame_source_.get(),
-                                                  frame_sink_id_);
-  }
-  display_->Initialize(this, frame_sink_manager_->surface_manager());
-  display_->renderer_for_testing()->SetEnlargePassTextureAmountForTesting(
-      enlarge_pass_texture_amount_);
-  display_->SetVisible(true);
-  return true;
-}
-
-void TestLayerTreeFrameSink::DetachFromClient() {
-  if (begin_frame_source_)
-    frame_sink_manager_->UnregisterBeginFrameSource(begin_frame_source_.get());
-  client_->SetBeginFrameSource(nullptr);
-  support_ = nullptr;
-  display_ = nullptr;
-  begin_frame_source_ = nullptr;
-  local_surface_id_allocator_ = nullptr;
-  frame_sink_manager_ = nullptr;
-  test_client_ = nullptr;
-  LayerTreeFrameSink::DetachFromClient();
-}
-
-void TestLayerTreeFrameSink::SetLocalSurfaceId(
-    const viz::LocalSurfaceId& local_surface_id) {
-  test_client_->DisplayReceivedLocalSurfaceId(local_surface_id);
-}
-
-void TestLayerTreeFrameSink::SubmitCompositorFrame(CompositorFrame frame) {
-  DCHECK(frame.metadata.begin_frame_ack.has_damage);
-  DCHECK_LE(BeginFrameArgs::kStartingFrameNumber,
-            frame.metadata.begin_frame_ack.sequence_number);
-  test_client_->DisplayReceivedCompositorFrame(frame);
-
-  gfx::Size frame_size = frame.render_pass_list.back()->output_rect.size();
-  float device_scale_factor = frame.metadata.device_scale_factor;
-  if (!local_surface_id_.is_valid() || frame_size != display_size_ ||
-      device_scale_factor != device_scale_factor_) {
-    local_surface_id_ = local_surface_id_allocator_->GenerateId();
-    display_->SetLocalSurfaceId(local_surface_id_, device_scale_factor);
-    display_->Resize(frame_size);
-    display_size_ = frame_size;
-    device_scale_factor_ = device_scale_factor;
-  }
-
-  bool result =
-      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
-  DCHECK(result);
-
-  for (std::unique_ptr<CopyOutputRequest>& copy_request : copy_requests_) {
-    support_->RequestCopyOfSurface(std::move(copy_request));
-  }
-  copy_requests_.clear();
-
-  if (!display_->has_scheduler()) {
-    display_->DrawAndSwap();
-    // Post this to get a new stack frame so that we exit this function before
-    // calling the client to tell it that it is done.
-    task_runner_->PostTask(
-        FROM_HERE,
-        base::BindOnce(&TestLayerTreeFrameSink::SendCompositorFrameAckToClient,
-                       weak_ptr_factory_.GetWeakPtr()));
-  }
-}
-
-void TestLayerTreeFrameSink::DidNotProduceFrame(const BeginFrameAck& ack) {
-  DCHECK(!ack.has_damage);
-  DCHECK_LE(BeginFrameArgs::kStartingFrameNumber, ack.sequence_number);
-  support_->DidNotProduceFrame(ack);
-}
-
-void TestLayerTreeFrameSink::DidReceiveCompositorFrameAck(
-    const std::vector<ReturnedResource>& resources) {
-  ReclaimResources(resources);
-  // In synchronous mode, we manually send acks and this method should not be
-  // used.
-  if (!display_->has_scheduler())
-    return;
-  client_->DidReceiveCompositorFrameAck();
-}
-
-void TestLayerTreeFrameSink::OnBeginFrame(const BeginFrameArgs& args) {
-  external_begin_frame_source_.OnBeginFrame(args);
-}
-
-void TestLayerTreeFrameSink::ReclaimResources(
-    const std::vector<ReturnedResource>& resources) {
-  client_->ReclaimResources(resources);
-}
-
-void TestLayerTreeFrameSink::WillDrawSurface(
-    const viz::LocalSurfaceId& local_surface_id,
-    const gfx::Rect& damage_rect) {}
-
-void TestLayerTreeFrameSink::DisplayOutputSurfaceLost() {
-  client_->DidLoseLayerTreeFrameSink();
-}
-
-void TestLayerTreeFrameSink::DisplayWillDrawAndSwap(
-    bool will_draw_and_swap,
-    const RenderPassList& render_passes) {
-  test_client_->DisplayWillDrawAndSwap(will_draw_and_swap, render_passes);
-}
-
-void TestLayerTreeFrameSink::DisplayDidDrawAndSwap() {
-  test_client_->DisplayDidDrawAndSwap();
-}
-
-void TestLayerTreeFrameSink::OnNeedsBeginFrames(bool needs_begin_frames) {
-  support_->SetNeedsBeginFrame(needs_begin_frames);
-}
-
-void TestLayerTreeFrameSink::SendCompositorFrameAckToClient() {
-  client_->DidReceiveCompositorFrameAck();
-}
-
-}  // namespace cc
diff --git a/cc/test/test_layer_tree_frame_sink.h b/cc/test/test_layer_tree_frame_sink.h
deleted file mode 100644
index 2f0f5dde..0000000
--- a/cc/test/test_layer_tree_frame_sink.h
+++ /dev/null
@@ -1,141 +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_TEST_TEST_LAYER_TREE_FRAME_SINK_H_
-#define CC_TEST_TEST_LAYER_TREE_FRAME_SINK_H_
-
-#include "base/memory/ref_counted.h"
-#include "base/memory/weak_ptr.h"
-#include "cc/output/layer_tree_frame_sink.h"
-#include "cc/output/renderer_settings.h"
-#include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
-#include "cc/surfaces/display.h"
-#include "cc/surfaces/display_client.h"
-#include "cc/surfaces/frame_sink_manager.h"
-#include "components/viz/common/local_surface_id_allocator.h"
-
-namespace base {
-class SingleThreadTaskRunner;
-}
-
-namespace cc {
-class CompositorFrameSinkSupport;
-class CopyOutputRequest;
-class OutputSurface;
-
-class TestLayerTreeFrameSinkClient {
- public:
-  virtual ~TestLayerTreeFrameSinkClient() {}
-
-  // This passes the ContextProvider being used by LayerTreeHostImpl which
-  // can be used for the OutputSurface optionally.
-  virtual std::unique_ptr<OutputSurface> CreateDisplayOutputSurface(
-      scoped_refptr<ContextProvider> compositor_context_provider) = 0;
-
-  virtual void DisplayReceivedLocalSurfaceId(
-      const viz::LocalSurfaceId& local_surface_id) = 0;
-  virtual void DisplayReceivedCompositorFrame(const CompositorFrame& frame) = 0;
-  virtual void DisplayWillDrawAndSwap(bool will_draw_and_swap,
-                                      const RenderPassList& render_passes) = 0;
-  virtual void DisplayDidDrawAndSwap() = 0;
-};
-
-// LayerTreeFrameSink that owns and forwards frames to a Display.
-class TestLayerTreeFrameSink : public LayerTreeFrameSink,
-                               public CompositorFrameSinkSupportClient,
-                               public DisplayClient,
-                               public ExternalBeginFrameSourceClient {
- public:
-  // Pass true for |force_disable_reclaim_resources| to act like the Display
-  // is out-of-process and can't return resources synchronously.
-  TestLayerTreeFrameSink(
-      scoped_refptr<ContextProvider> compositor_context_provider,
-      scoped_refptr<ContextProvider> worker_context_provider,
-      viz::SharedBitmapManager* shared_bitmap_manager,
-      gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
-      const RendererSettings& renderer_settings,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
-      bool synchronous_composite,
-      bool disable_display_vsync,
-      double refresh_rate);
-  ~TestLayerTreeFrameSink() override;
-
-  // This client must be set before BindToClient() happens.
-  void SetClient(TestLayerTreeFrameSinkClient* client) {
-    test_client_ = client;
-  }
-  void SetEnlargePassTextureAmount(const gfx::Size& s) {
-    enlarge_pass_texture_amount_ = s;
-  }
-
-  Display* display() const { return display_.get(); }
-
-  // Will be included with the next SubmitCompositorFrame.
-  void RequestCopyOfOutput(std::unique_ptr<CopyOutputRequest> request);
-
-  // LayerTreeFrameSink implementation.
-  bool BindToClient(LayerTreeFrameSinkClient* client) override;
-  void DetachFromClient() override;
-  void SetLocalSurfaceId(const viz::LocalSurfaceId& local_surface_id) override;
-  void SubmitCompositorFrame(CompositorFrame frame) override;
-  void DidNotProduceFrame(const BeginFrameAck& ack) override;
-
-  // CompositorFrameSinkSupportClient implementation.
-  void DidReceiveCompositorFrameAck(
-      const std::vector<ReturnedResource>& resources) override;
-  void OnBeginFrame(const BeginFrameArgs& args) override;
-  void ReclaimResources(
-      const std::vector<ReturnedResource>& resources) override;
-  void WillDrawSurface(const viz::LocalSurfaceId& local_surface_id,
-                       const gfx::Rect& damage_rect) override;
-
-  // DisplayClient implementation.
-  void DisplayOutputSurfaceLost() override;
-  void DisplayWillDrawAndSwap(bool will_draw_and_swap,
-                              const RenderPassList& render_passes) override;
-  void DisplayDidDrawAndSwap() override;
-
- private:
-  // ExternalBeginFrameSource implementation.
-  void OnNeedsBeginFrames(bool needs_begin_frames) override;
-
-  void SendCompositorFrameAckToClient();
-
-  const bool synchronous_composite_;
-  const bool disable_display_vsync_;
-  const RendererSettings renderer_settings_;
-  const double refresh_rate_;
-
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-
-  viz::FrameSinkId frame_sink_id_;
-  // TODO(danakj): These don't need to be stored in unique_ptrs when
-  // LayerTreeFrameSink is owned/destroyed on the compositor thread.
-  std::unique_ptr<FrameSinkManager> frame_sink_manager_;
-  std::unique_ptr<viz::LocalSurfaceIdAllocator> local_surface_id_allocator_;
-  viz::LocalSurfaceId local_surface_id_;
-  gfx::Size display_size_;
-  float device_scale_factor_ = 0;
-
-  // Uses surface_manager_.
-  std::unique_ptr<CompositorFrameSinkSupport> support_;
-
-  std::unique_ptr<SyntheticBeginFrameSource> begin_frame_source_;
-  ExternalBeginFrameSource external_begin_frame_source_;
-
-  // Uses surface_manager_ and begin_frame_source_.
-  std::unique_ptr<Display> display_;
-
-  TestLayerTreeFrameSinkClient* test_client_ = nullptr;
-  gfx::Size enlarge_pass_texture_amount_;
-
-  std::vector<std::unique_ptr<CopyOutputRequest>> copy_requests_;
-
-  base::WeakPtrFactory<TestLayerTreeFrameSink> weak_ptr_factory_;
-};
-
-}  // namespace cc
-
-#endif  // CC_TEST_TEST_LAYER_TREE_FRAME_SINK_H_
diff --git a/cc/tiles/checker_image_tracker.cc b/cc/tiles/checker_image_tracker.cc
index c9e4228..2561744 100644
--- a/cc/tiles/checker_image_tracker.cc
+++ b/cc/tiles/checker_image_tracker.cc
@@ -6,6 +6,7 @@
 
 #include "base/bind.h"
 #include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
 #include "base/stl_util.h"
 #include "base/trace_event/trace_event.h"
 
@@ -14,29 +15,100 @@
 // The minimum size of an image that we should consider checkering.
 size_t kMinImageSizeToCheckerBytes = 512 * 1024;
 
-size_t SafeSizeOfImage(const SkImage* image) {
-  base::CheckedNumeric<size_t> checked_size = 4;
-  checked_size *= image->width();
-  checked_size *= image->height();
-  return checked_size.ValueOrDefault(std::numeric_limits<size_t>::max());
-}
+// The enum for recording checker-imaging decision UMA metric. Keep this
+// consistent with the ordering in CheckerImagingDecision in enums.xml.
+// Note that this enum is used to back a UMA histogram so should be treated as
+// append only.
+enum class CheckerImagingDecision {
+  kCanChecker,
+
+  // Animation State vetoes.
+  kVetoedAnimatedImage,
+  kVetoedVideoFrame,
+  kVetoedAnimationUnknown,
+  kVetoedMultipartImage,
+
+  // Load state vetoes.
+  kVetoedPartiallyLoadedImage,
+  kVetoedLoadStateUnknown,
+
+  // Size associated vetoes.
+  kVetoedSmallerThanCheckeringSize,
+  kVetoedLargerThanCacheSize,
+
+  kCheckerImagingDecisionCount,
+};
 
 std::string ToString(PaintImage::Id paint_image_id,
                      SkImageId sk_image_id,
-                     bool complete,
-                     bool static_image,
-                     bool fits_size_constraints,
-                     bool is_multipart,
-                     size_t size) {
+                     CheckerImagingDecision decision) {
   std::ostringstream str;
   str << "paint_image_id[" << paint_image_id << "] sk_image_id[" << sk_image_id
-      << "] complete[" << complete << "] static[" << static_image
-      << "], fits_size_constraints[" << fits_size_constraints << "], size["
-      << size << "]"
-      << " is_multipart[" << is_multipart << "]";
+      << "] decision[" << static_cast<int>(decision) << "]";
   return str.str();
 }
 
+CheckerImagingDecision GetAnimationDecision(const PaintImage& image) {
+  if (image.is_multipart())
+    return CheckerImagingDecision::kVetoedMultipartImage;
+
+  switch (image.animation_type()) {
+    case PaintImage::AnimationType::UNKNOWN:
+      return CheckerImagingDecision::kVetoedAnimationUnknown;
+    case PaintImage::AnimationType::ANIMATED:
+      return CheckerImagingDecision::kVetoedAnimatedImage;
+    case PaintImage::AnimationType::VIDEO:
+      return CheckerImagingDecision::kVetoedVideoFrame;
+    case PaintImage::AnimationType::STATIC:
+      return CheckerImagingDecision::kCanChecker;
+  }
+
+  NOTREACHED();
+  return CheckerImagingDecision::kCanChecker;
+}
+
+CheckerImagingDecision GetLoadDecision(const PaintImage& image) {
+  switch (image.completion_state()) {
+    case PaintImage::CompletionState::UNKNOWN:
+      return CheckerImagingDecision::kVetoedLoadStateUnknown;
+    case PaintImage::CompletionState::DONE:
+      return CheckerImagingDecision::kCanChecker;
+    case PaintImage::CompletionState::PARTIALLY_DONE:
+      return CheckerImagingDecision::kVetoedPartiallyLoadedImage;
+  }
+
+  NOTREACHED();
+  return CheckerImagingDecision::kCanChecker;
+}
+
+CheckerImagingDecision GetSizeDecision(const PaintImage& image,
+                                       size_t max_bytes) {
+  base::CheckedNumeric<size_t> checked_size = 4;
+  checked_size *= image.sk_image()->width();
+  checked_size *= image.sk_image()->height();
+  size_t size = checked_size.ValueOrDefault(std::numeric_limits<size_t>::max());
+
+  if (size < kMinImageSizeToCheckerBytes)
+    return CheckerImagingDecision::kVetoedSmallerThanCheckeringSize;
+  else if (size > max_bytes)
+    return CheckerImagingDecision::kVetoedLargerThanCacheSize;
+  else
+    return CheckerImagingDecision::kCanChecker;
+}
+
+CheckerImagingDecision GetCheckerImagingDecision(const PaintImage& image,
+                                                 size_t max_bytes) {
+  CheckerImagingDecision decision = GetAnimationDecision(image);
+  if (decision != CheckerImagingDecision::kCanChecker)
+    return decision;
+
+  decision = GetLoadDecision(image);
+  if (decision != CheckerImagingDecision::kCanChecker)
+    return decision;
+
+  return GetSizeDecision(image, max_bytes);
+}
+
 }  // namespace
 
 // static
@@ -207,15 +279,6 @@
       std::pair<PaintImage::Id, DecodeState>(image_id, DecodeState()));
   auto it = insert_result.first;
   if (insert_result.second) {
-    bool complete =
-        image.completion_state() == PaintImage::CompletionState::DONE;
-    bool static_image =
-        image.animation_type() == PaintImage::AnimationType::STATIC;
-    size_t size = SafeSizeOfImage(image.sk_image().get());
-    bool fits_size_constraints =
-        size >= kMinImageSizeToCheckerBytes &&
-        size <= image_controller_->image_cache_max_limit_bytes();
-
     // The following conditions must be true for an image to be checkerable:
     //
     // 1) Complete: The data for the image should have been completely loaded.
@@ -229,17 +292,19 @@
     // 4) Multipart images: Multipart images can be used to display mjpg video
     // frames, checkering which would cause each video frame to flash and
     // therefore should not be checkered.
-    bool can_checker_image = complete && static_image &&
-                             fits_size_constraints && !image.is_multipart();
-    if (can_checker_image)
-      it->second.policy = DecodePolicy::ASYNC;
+    CheckerImagingDecision decision = GetCheckerImagingDecision(
+        image, image_controller_->image_cache_max_limit_bytes());
+    it->second.policy = decision == CheckerImagingDecision::kCanChecker
+                            ? DecodePolicy::ASYNC
+                            : DecodePolicy::SYNC;
 
-    TRACE_EVENT2(
-        TRACE_DISABLED_BY_DEFAULT("cc.debug"),
-        "CheckerImageTracker::CheckerImagingDecision", "can_checker_image",
-        can_checker_image, "image_params",
-        ToString(image_id, image.sk_image()->uniqueID(), complete, static_image,
-                 fits_size_constraints, image.is_multipart(), size));
+    UMA_HISTOGRAM_ENUMERATION(
+        "Compositing.Renderer.CheckerImagingDecision", decision,
+        CheckerImagingDecision::kCheckerImagingDecisionCount);
+
+    TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
+                 "CheckerImageTracker::CheckerImagingDecision", "image_params",
+                 ToString(image_id, image.sk_image()->uniqueID(), decision));
   }
 
   // Update the decode state from the latest image we have seen. Note that it
diff --git a/cc/trees/layer_tree_host_common_perftest.cc b/cc/trees/layer_tree_host_common_perftest.cc
index c0b1e32..b20ceedc 100644
--- a/cc/trees/layer_tree_host_common_perftest.cc
+++ b/cc/trees/layer_tree_host_common_perftest.cc
@@ -20,9 +20,9 @@
 #include "cc/test/fake_layer_tree_host_client.h"
 #include "cc/test/layer_tree_json_parser.h"
 #include "cc/test/layer_tree_test.h"
-#include "cc/test/paths.h"
 #include "cc/trees/layer_tree_host_common.h"
 #include "cc/trees/layer_tree_impl.h"
+#include "components/viz/test/paths.h"
 #include "testing/perf/perf_test.h"
 
 namespace cc {
@@ -41,7 +41,7 @@
 
   void ReadTestFile(const std::string& name) {
     base::FilePath test_data_dir;
-    ASSERT_TRUE(PathService::Get(CCPaths::DIR_TEST_DATA, &test_data_dir));
+    ASSERT_TRUE(PathService::Get(viz::Paths::DIR_TEST_DATA, &test_data_dir));
     base::FilePath json_file = test_data_dir.AppendASCII(name + ".json");
     ASSERT_TRUE(base::ReadFileToString(json_file, &json_));
   }
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 431f74a..f9581d2 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -61,7 +61,6 @@
 #include "cc/test/layer_test_common.h"
 #include "cc/test/layer_tree_test.h"
 #include "cc/test/skia_common.h"
-#include "cc/test/test_layer_tree_frame_sink.h"
 #include "cc/test/test_task_graph_runner.h"
 #include "cc/test/test_web_graphics_context_3d.h"
 #include "cc/trees/effect_node.h"
@@ -71,6 +70,7 @@
 #include "cc/trees/scroll_node.h"
 #include "cc/trees/single_thread_proxy.h"
 #include "cc/trees/transform_node.h"
+#include "components/viz/test/test_layer_tree_frame_sink.h"
 #include "media/base/media.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -8783,7 +8783,7 @@
 void ShutdownReleasesContext_Callback(
     std::unique_ptr<CopyOutputResult> result) {}
 
-class FrameSinkClient : public TestLayerTreeFrameSinkClient {
+class FrameSinkClient : public viz::TestLayerTreeFrameSinkClient {
  public:
   explicit FrameSinkClient(
       scoped_refptr<ContextProvider> display_context_provider)
@@ -8813,7 +8813,7 @@
   constexpr bool synchronous_composite = true;
   constexpr bool disable_display_vsync = false;
   constexpr double refresh_rate = 60.0;
-  auto layer_tree_frame_sink = base::MakeUnique<TestLayerTreeFrameSink>(
+  auto layer_tree_frame_sink = base::MakeUnique<viz::TestLayerTreeFrameSink>(
       context_provider, TestContextProvider::CreateWorker(), nullptr, nullptr,
       RendererSettings(), base::ThreadTaskRunnerHandle::Get().get(),
       synchronous_composite, disable_display_vsync, refresh_rate);
diff --git a/cc/trees/layer_tree_host_perftest.cc b/cc/trees/layer_tree_host_perftest.cc
index 30553919..f1c354b 100644
--- a/cc/trees/layer_tree_host_perftest.cc
+++ b/cc/trees/layer_tree_host_perftest.cc
@@ -21,10 +21,10 @@
 #include "cc/test/fake_content_layer_client.h"
 #include "cc/test/layer_tree_json_parser.h"
 #include "cc/test/layer_tree_test.h"
-#include "cc/test/paths.h"
-#include "cc/test/test_layer_tree_frame_sink.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "components/viz/common/quads/texture_mailbox.h"
+#include "components/viz/test/paths.h"
+#include "components/viz/test/test_layer_tree_frame_sink.h"
 #include "testing/perf/perf_test.h"
 
 namespace cc {
@@ -46,7 +46,7 @@
         measure_commit_cost_(false) {
   }
 
-  std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+  std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
       const RendererSettings& renderer_settings,
       double refresh_rate,
       scoped_refptr<ContextProvider> compositor_context_provider,
@@ -55,7 +55,7 @@
     bool synchronous_composite =
         !HasImplThread() &&
         !layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
-    return base::MakeUnique<TestLayerTreeFrameSink>(
+    return base::MakeUnique<viz::TestLayerTreeFrameSink>(
         compositor_context_provider, std::move(worker_context_provider),
         shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings,
         ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync,
@@ -138,7 +138,7 @@
 
   void ReadTestFile(const std::string& name) {
     base::FilePath test_data_dir;
-    ASSERT_TRUE(PathService::Get(CCPaths::DIR_TEST_DATA, &test_data_dir));
+    ASSERT_TRUE(PathService::Get(viz::Paths::DIR_TEST_DATA, &test_data_dir));
     base::FilePath json_file = test_data_dir.AppendASCII(name + ".json");
     ASSERT_TRUE(base::ReadFileToString(json_file, &json_));
   }
diff --git a/cc/trees/layer_tree_host_pixeltest_blending.cc b/cc/trees/layer_tree_host_pixeltest_blending.cc
index 8cecb9e..b8a5018 100644
--- a/cc/trees/layer_tree_host_pixeltest_blending.cc
+++ b/cc/trees/layer_tree_host_pixeltest_blending.cc
@@ -9,7 +9,7 @@
 #include "cc/paint/paint_image.h"
 #include "cc/test/layer_tree_pixel_resource_test.h"
 #include "cc/test/pixel_comparator.h"
-#include "cc/test/test_layer_tree_frame_sink.h"
+#include "components/viz/test/test_layer_tree_frame_sink.h"
 #include "third_party/skia/include/core/SkImage.h"
 #include "third_party/skia/include/core/SkSurface.h"
 
@@ -69,7 +69,7 @@
   }
 
  protected:
-  std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+  std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
       const RendererSettings& renderer_settings,
       double refresh_rate,
       scoped_refptr<ContextProvider> compositor_context_provider,
diff --git a/cc/trees/layer_tree_host_pixeltest_readback.cc b/cc/trees/layer_tree_host_pixeltest_readback.cc
index 85bcf51..4a605a0d 100644
--- a/cc/trees/layer_tree_host_pixeltest_readback.cc
+++ b/cc/trees/layer_tree_host_pixeltest_readback.cc
@@ -10,9 +10,9 @@
 #include "cc/test/fake_picture_layer.h"
 #include "cc/test/fake_picture_layer_impl.h"
 #include "cc/test/layer_tree_pixel_test.h"
-#include "cc/test/paths.h"
 #include "cc/test/solid_color_content_layer_client.h"
 #include "cc/trees/layer_tree_impl.h"
+#include "components/viz/test/paths.h"
 
 #if !defined(OS_ANDROID)
 
diff --git a/cc/trees/layer_tree_host_pixeltest_tiles.cc b/cc/trees/layer_tree_host_pixeltest_tiles.cc
index c4ff86c..58d1140e 100644
--- a/cc/trees/layer_tree_host_pixeltest_tiles.cc
+++ b/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -11,7 +11,7 @@
 #include "cc/paint/paint_flags.h"
 #include "cc/paint/paint_op_buffer.h"
 #include "cc/test/layer_tree_pixel_test.h"
-#include "cc/test/test_layer_tree_frame_sink.h"
+#include "components/viz/test/test_layer_tree_frame_sink.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 
 #if !defined(OS_ANDROID)
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 5afe760..9eba327 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -52,7 +52,6 @@
 #include "cc/test/push_properties_counting_layer_impl.h"
 #include "cc/test/render_pass_test_utils.h"
 #include "cc/test/skia_common.h"
-#include "cc/test/test_layer_tree_frame_sink.h"
 #include "cc/test/test_web_graphics_context_3d.h"
 #include "cc/trees/clip_node.h"
 #include "cc/trees/effect_node.h"
@@ -64,6 +63,7 @@
 #include "cc/trees/single_thread_proxy.h"
 #include "cc/trees/swap_promise_manager.h"
 #include "cc/trees/transform_node.h"
+#include "components/viz/test/test_layer_tree_frame_sink.h"
 #include "gpu/GLES2/gl2extchromium.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "third_party/khronos/GLES2/gl2.h"
@@ -441,7 +441,7 @@
 
 class LayerTreeHostContextCacheTest : public LayerTreeHostTest {
  public:
-  std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+  std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
       const RendererSettings& renderer_settings,
       double refresh_rate,
       scoped_refptr<ContextProvider> compositor_context_provider,
@@ -3360,7 +3360,7 @@
   int commit_complete_count_;
 };
 
-class OnDrawLayerTreeFrameSink : public TestLayerTreeFrameSink {
+class OnDrawLayerTreeFrameSink : public viz::TestLayerTreeFrameSink {
  public:
   OnDrawLayerTreeFrameSink(
       scoped_refptr<ContextProvider> compositor_context_provider,
@@ -3404,7 +3404,7 @@
     settings->using_synchronous_renderer_compositor = true;
   }
 
-  std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+  std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
       const RendererSettings& renderer_settings,
       double refresh_rate,
       scoped_refptr<ContextProvider> compositor_context_provider,
@@ -5535,7 +5535,7 @@
 
 class LayerTreeHostWithGpuRasterizationTest : public LayerTreeHostTest {
  protected:
-  std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+  std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
       const RendererSettings& renderer_settings,
       double refresh_rate,
       scoped_refptr<ContextProvider> compositor_context_provider,
@@ -6065,7 +6065,7 @@
     settings->use_zero_copy = true;
   }
 
-  std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+  std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
       const RendererSettings& renderer_settings,
       double refresh_rate,
       scoped_refptr<ContextProvider> compositor_context_provider,
@@ -6074,7 +6074,7 @@
     bool synchronous_composite =
         !HasImplThread() &&
         !layer_tree_host()->GetSettings().single_thread_proxy_scheduler;
-    return base::MakeUnique<TestLayerTreeFrameSink>(
+    return base::MakeUnique<viz::TestLayerTreeFrameSink>(
         compositor_context_provider, std::move(worker_context_provider),
         shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings,
         ImplThreadTaskRunner(), synchronous_composite, disable_display_vsync,
diff --git a/cc/trees/layer_tree_host_unittest_checkerimaging.cc b/cc/trees/layer_tree_host_unittest_checkerimaging.cc
index 0fe9dc1..2e4ca84f 100644
--- a/cc/trees/layer_tree_host_unittest_checkerimaging.cc
+++ b/cc/trees/layer_tree_host_unittest_checkerimaging.cc
@@ -9,8 +9,8 @@
 #include "cc/test/fake_picture_layer.h"
 #include "cc/test/layer_tree_test.h"
 #include "cc/test/skia_common.h"
-#include "cc/test/test_layer_tree_frame_sink.h"
 #include "cc/trees/layer_tree_impl.h"
+#include "components/viz/test/test_layer_tree_frame_sink.h"
 
 namespace cc {
 namespace {
diff --git a/cc/trees/layer_tree_host_unittest_context.cc b/cc/trees/layer_tree_host_unittest_context.cc
index 1673a974..e14401b 100644
--- a/cc/trees/layer_tree_host_unittest_context.cc
+++ b/cc/trees/layer_tree_host_unittest_context.cc
@@ -30,13 +30,13 @@
 #include "cc/test/layer_tree_test.h"
 #include "cc/test/render_pass_test_utils.h"
 #include "cc/test/test_context_provider.h"
-#include "cc/test/test_layer_tree_frame_sink.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "cc/test/test_web_graphics_context_3d.h"
 #include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_host_impl.h"
 #include "cc/trees/layer_tree_impl.h"
 #include "cc/trees/single_thread_proxy.h"
+#include "components/viz/test/test_layer_tree_frame_sink.h"
 #include "gpu/GLES2/gl2extchromium.h"
 #include "media/base/media.h"
 
@@ -77,7 +77,7 @@
     context3d_ = nullptr;
   }
 
-  std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+  std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
       const RendererSettings& renderer_settings,
       double refresh_rate,
       scoped_refptr<ContextProvider> compositor_context_provider,
diff --git a/cc/trees/layer_tree_host_unittest_copyrequest.cc b/cc/trees/layer_tree_host_unittest_copyrequest.cc
index 3eda715..22f5ca1 100644
--- a/cc/trees/layer_tree_host_unittest_copyrequest.cc
+++ b/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -12,13 +12,12 @@
 #include "cc/output/copy_output_request.h"
 #include "cc/output/copy_output_result.h"
 #include "cc/output/direct_renderer.h"
-#include "cc/surfaces/display.h"
 #include "cc/test/fake_content_layer_client.h"
 #include "cc/test/fake_output_surface.h"
 #include "cc/test/fake_picture_layer.h"
 #include "cc/test/layer_tree_test.h"
-#include "cc/test/test_layer_tree_frame_sink.h"
 #include "cc/trees/layer_tree_impl.h"
+#include "components/viz/test/test_layer_tree_frame_sink.h"
 #include "gpu/GLES2/gl2extchromium.h"
 
 namespace cc {
@@ -464,7 +463,7 @@
     client_.set_bounds(root_->bounds());
   }
 
-  std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
+  std::unique_ptr<viz::TestLayerTreeFrameSink> CreateLayerTreeFrameSink(
       const RendererSettings& renderer_settings,
       double refresh_rate,
       scoped_refptr<ContextProvider> compositor_context_provider,
@@ -536,7 +535,7 @@
 
   RenderPassId parent_render_pass_id = 0;
   RenderPassId copy_layer_render_pass_id = 0;
-  TestLayerTreeFrameSink* frame_sink_ = nullptr;
+  viz::TestLayerTreeFrameSink* frame_sink_ = nullptr;
   bool did_swap_ = false;
   FakeContentLayerClient client_;
   scoped_refptr<FakePictureLayer> root_;
diff --git a/cc/trees/layer_tree_impl.cc b/cc/trees/layer_tree_impl.cc
index 1f78845..e4ad455 100644
--- a/cc/trees/layer_tree_impl.cc
+++ b/cc/trees/layer_tree_impl.cc
@@ -1657,15 +1657,20 @@
     return;
 
   auto& scrollbar_ids = element_id_to_scrollbar_layer_ids_[scroll_element_id];
-  if (scrollbar_layer->orientation() == HORIZONTAL) {
-    DCHECK_EQ(scrollbar_ids.horizontal, Layer::INVALID_ID)
-        << "Existing scrollbar should have been unregistered.";
-    scrollbar_ids.horizontal = scrollbar_layer->id();
-  } else {
-    DCHECK_EQ(scrollbar_ids.vertical, Layer::INVALID_ID)
-        << "Existing scrollbar should have been unregistered.";
-    scrollbar_ids.vertical = scrollbar_layer->id();
-  }
+  int& scrollbar_layer_id = scrollbar_layer->orientation() == HORIZONTAL
+                                ? scrollbar_ids.horizontal
+                                : scrollbar_ids.vertical;
+
+  // We used to DCHECK this was not the case but this can occur on Android: as
+  // the visual viewport supplies scrollbars for the outer viewport, if the
+  // outer viewport is changed, we race between updating the visual viewport
+  // scrollbars and registering new scrollbars on the old outer viewport. It'd
+  // be nice if we could fix this to be cleaner but its harmless to just
+  // unregister here.
+  if (scrollbar_layer_id != Layer::INVALID_ID)
+    UnregisterScrollbar(scrollbar_layer);
+
+  scrollbar_layer_id = scrollbar_layer->id();
 
   if (IsActiveTree() && scrollbar_layer->is_overlay_scrollbar() &&
       scrollbar_layer->GetScrollbarAnimator() !=
diff --git a/cc/trees/proxy_main.cc b/cc/trees/proxy_main.cc
index 9628d47..9ca0ce8 100644
--- a/cc/trees/proxy_main.cc
+++ b/cc/trees/proxy_main.cc
@@ -212,20 +212,25 @@
     return;
   }
 
-  bool can_cancel_this_commit = final_pipeline_stage_ < COMMIT_PIPELINE_STAGE &&
-                                !begin_main_frame_state->evicted_ui_resources;
+  // If UI resources were evicted on the impl thread, we need a commit.
+  if (begin_main_frame_state->evicted_ui_resources)
+    final_pipeline_stage_ = COMMIT_PIPELINE_STAGE;
 
   current_pipeline_stage_ = UPDATE_LAYERS_PIPELINE_STAGE;
   bool should_update_layers =
       final_pipeline_stage_ >= UPDATE_LAYERS_PIPELINE_STAGE;
   bool updated = should_update_layers && layer_tree_host_->UpdateLayers();
 
+  // If updating the layers resulted in a content update, we need a commit.
+  if (updated)
+    final_pipeline_stage_ = COMMIT_PIPELINE_STAGE;
+
   layer_tree_host_->WillCommit();
   devtools_instrumentation::ScopedCommitTrace commit_task(
       layer_tree_host_->GetId());
 
   current_pipeline_stage_ = COMMIT_PIPELINE_STAGE;
-  if (!updated && can_cancel_this_commit) {
+  if (final_pipeline_stage_ < COMMIT_PIPELINE_STAGE) {
     TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoUpdates", TRACE_EVENT_SCOPE_THREAD);
     std::vector<std::unique_ptr<SwapPromise>> swap_promises =
         layer_tree_host_->GetSwapPromiseManager()->TakeSwapPromises();
diff --git a/chrome/android/java/AndroidManifest.xml b/chrome/android/java/AndroidManifest.xml
index 2c0c3b0..fa08d14 100644
--- a/chrome/android/java/AndroidManifest.xml
+++ b/chrome/android/java/AndroidManifest.xml
@@ -619,6 +619,19 @@
             android:excludeFromRecents="true">
         </activity>
 
+        <activity
+            android:name="org.chromium.chrome.browser.vr_shell.VrCancelAnimationActivity"
+            android:exported="false"
+            android:theme="@android:style/Theme.NoDisplay"
+            android:noHistory="true"
+            android:excludeFromRecents="true"
+            {% if enable_vr == "true" %}
+            android:enableVrMode="@string/gvr_vr_mode_component"
+            {% endif %}
+            >
+            {{ self.supports_vr() }}
+        </activity>
+
         <!-- Service for handling Nearby Messages -->
         <service android:name="org.chromium.chrome.browser.physicalweb.NearbyMessageIntentService"
             android:exported="false" />
diff --git a/chrome/android/java/res/anim/stay_hidden.xml b/chrome/android/java/res/anim/stay_hidden.xml
index be44bde0..69e10db 100644
--- a/chrome/android/java/res/anim/stay_hidden.xml
+++ b/chrome/android/java/res/anim/stay_hidden.xml
@@ -6,10 +6,8 @@
 
 <!-- The delay here must be long enough for the Activity being resumed to draw
      its first frame of UI. This is to avoid showing stale 2D screenshots when
-     launching Chrome in VR. Note that the larger this value is, the more
-     latency we add to resuming Chrome after going through the Daydream Device
-     ON flow. -->
+     launching Chrome in VR. We cancel this animation upon entering VR. -->
 <alpha xmlns:android="http://schemas.android.com/apk/res/android"
         android:interpolator="@android:anim/linear_interpolator"
         android:fromAlpha="0" android:toAlpha="0"
-        android:duration="500" />
+        android:duration="10000" />
diff --git a/chrome/android/java/res/menu/main_menu.xml b/chrome/android/java/res/menu/main_menu.xml
index 3b5aa0e3..5451359 100644
--- a/chrome/android/java/res/menu/main_menu.xml
+++ b/chrome/android/java/res/menu/main_menu.xml
@@ -95,6 +95,21 @@
              android:title="@string/menu_preferences" />
     </group>
 
+    <!-- Items shown only in the the BottomSheet NTP UI -->
+    <group android:id="@+id/BOTTOM_SHEET_NTP_MENU"
+        android:visible="false">
+         <item android:id="@id/new_tab_menu_id"
+             android:title="@string/menu_new_tab" />
+         <item android:id="@id/new_incognito_tab_menu_id"
+             android:title="@string/menu_new_incognito_tab" />
+         <item android:id="@id/recent_tabs_menu_id"
+            android:title="@string/menu_recent_tabs" />
+         <item android:id="@id/preferences_id"
+             android:title="@string/menu_preferences" />
+         <item android:id="@id/help_id"
+            android:title="@string/menu_help" />
+    </group>
+
     <!-- Items shown only when the tablet has no visible tabs -->
     <group android:id="@+id/TABLET_EMPTY_MODE_MENU"
         android:visible="false">
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
index d415947..69a2e0af 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java
@@ -111,6 +111,7 @@
 import org.chromium.chrome.browser.preferences.PreferencesLauncher;
 import org.chromium.chrome.browser.printing.PrintShareActivity;
 import org.chromium.chrome.browser.printing.TabPrinter;
+import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.share.OptionalShareTargetsManager;
 import org.chromium.chrome.browser.share.ShareActivity;
 import org.chromium.chrome.browser.share.ShareHelper;
@@ -1873,8 +1874,22 @@
             return true;
         }
 
-        // All the code below assumes currentTab is not null, so return early if it is null.
         final Tab currentTab = getActivityTab();
+
+        if (id == R.id.help_id) {
+            String url = currentTab != null
+                    ? currentTab.getUrl()
+                    : getBottomSheet() != null && mBottomSheet.isShowingNewTab()
+                            ? UrlConstants.NTP_URL
+                            : "";
+            Profile profile = mTabModelSelector.isIncognitoSelected()
+                    ? Profile.getLastUsedProfile().getOffTheRecordProfile()
+                    : Profile.getLastUsedProfile().getOriginalProfile();
+            startHelpAndFeedback(url, "MobileMenuFeedback", profile);
+            return true;
+        }
+
+        // All the code below assumes currentTab is not null, so return early if it is null.
         if (currentTab == null) {
             return false;
         } else if (id == R.id.forward_menu_id) {
@@ -1962,8 +1977,6 @@
                 builder.setView(DistilledPagePrefsView.create(this));
                 builder.show();
             }
-        } else if (id == R.id.help_id) {
-            startHelpAndFeedback(currentTab, "MobileMenuFeedback");
         } else {
             return false;
         }
@@ -1972,16 +1985,16 @@
 
     /**
      * Shows HelpAndFeedback and records the user action as well.
-     * @param currentTab The tab that the user is currently on.
+     * @param url The URL of the tab the user is currently on.
      * @param recordAction The user action to record.
+     * @param profile The current {@link Profile}.
      */
-    public void startHelpAndFeedback(Tab currentTab, String recordAction) {
+    public void startHelpAndFeedback(String url, String recordAction, Profile profile) {
         // Since reading back the compositor is asynchronous, we need to do the readback
         // before starting the GoogleHelp.
         String helpContextId = HelpAndFeedback.getHelpContextIdFromUrl(
-                this, currentTab.getUrl(), getCurrentTabModel().isIncognito());
-        HelpAndFeedback.getInstance(this)
-                .show(this, helpContextId, currentTab.getProfile(), currentTab.getUrl());
+                this, url, getCurrentTabModel().isIncognito());
+        HelpAndFeedback.getInstance(this).show(this, helpContextId, profile, url);
         RecordUserAction.record(recordAction);
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
index 5d33232..64aa6da 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -1643,13 +1643,19 @@
                 RecordUserAction.record("MobileMenuAllBookmarks");
             }
         } else if (id == R.id.recent_tabs_menu_id) {
-            if (currentTab != null) {
-                currentTab.loadUrl(new LoadUrlParams(
-                        UrlConstants.RECENT_TABS_URL,
-                        PageTransition.AUTO_BOOKMARK));
-                if (currentTabIsNtp) {
-                    NewTabPageUma.recordAction(NewTabPageUma.ACTION_OPENED_RECENT_TABS_MANAGER);
+            if (currentTab != null
+                    || (getBottomSheet() != null && getBottomSheet().isShowingNewTab())) {
+                LoadUrlParams params = new LoadUrlParams(
+                        UrlConstants.RECENT_TABS_URL, PageTransition.AUTO_BOOKMARK);
+                if (currentTab != null) {
+                    currentTab.loadUrl(params);
+                    if (currentTabIsNtp) {
+                        NewTabPageUma.recordAction(NewTabPageUma.ACTION_OPENED_RECENT_TABS_MANAGER);
+                    }
+                } else {
+                    getBottomSheet().loadUrl(params, getCurrentTabModel().isIncognito());
                 }
+
                 RecordUserAction.record("MobileMenuRecentTabs");
             }
         } else if (id == R.id.close_all_tabs_menu_id) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java
index a537cfd..a54b546 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/appmenu/AppMenuPropertiesDelegate.java
@@ -75,6 +75,8 @@
         boolean isPageMenu;
         boolean isOverviewMenu;
         boolean isTabletEmptyModeMenu;
+        boolean isBottomSheetNtpMenu =
+                mActivity.getBottomSheet() != null && mActivity.getBottomSheet().isShowingNewTab();
 
         boolean isOverview = mActivity.isInOverviewMode();
         boolean isIncognito = mActivity.getCurrentTabModel().isIncognito();
@@ -87,13 +89,14 @@
             isOverviewMenu = hasTabs && isOverview;
             isTabletEmptyModeMenu = !hasTabs;
         } else {
-            isPageMenu = !isOverview;
-            isOverviewMenu = isOverview;
+            isPageMenu = !isBottomSheetNtpMenu && !isOverview;
+            isOverviewMenu = !isBottomSheetNtpMenu && isOverview;
             isTabletEmptyModeMenu = false;
         }
 
         menu.setGroupVisible(R.id.PAGE_MENU, isPageMenu);
         menu.setGroupVisible(R.id.OVERVIEW_MODE_MENU, isOverviewMenu);
+        menu.setGroupVisible(R.id.BOTTOM_SHEET_NTP_MENU, isBottomSheetNtpMenu);
         menu.setGroupVisible(R.id.TABLET_EMPTY_MODE_MENU, isTabletEmptyModeMenu);
 
         if (isPageMenu && currentTab != null) {
@@ -211,12 +214,17 @@
             }
         }
 
+        if (isBottomSheetNtpMenu) {
+            disableEnableMenuItem(menu, R.id.recent_tabs_menu_id, !isIncognito, true, false);
+            disableEnableMenuItem(menu, R.id.new_tab_menu_id, isIncognito, true, false);
+        }
+
+        boolean incognitoMenuItemVisible = !isBottomSheetNtpMenu || !isIncognito;
         // Disable new incognito tab when it is blocked (e.g. by a policy).
         // findItem(...).setEnabled(...)" is not enough here, because of the inflated
         // main_menu.xml contains multiple items with the same id in different groups
         // e.g.: new_incognito_tab_menu_id.
-        disableEnableMenuItem(menu, R.id.new_incognito_tab_menu_id,
-                true,
+        disableEnableMenuItem(menu, R.id.new_incognito_tab_menu_id, incognitoMenuItemVisible,
                 PrefServiceBridge.getInstance().isIncognitoModeEnabled(),
                 PrefServiceBridge.getInstance().isIncognitoModeManaged());
         mActivity.prepareMenu(menu);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java
index 82348ac..8c2e12ba 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/document/ChromeLauncherActivity.java
@@ -196,7 +196,7 @@
 
         // Check if we should launch the ChromeTabbedActivity.
         if (!mIsCustomTabIntent && !FeatureUtilities.isDocumentMode(this)) {
-            launchTabbedMode(false);
+            launchTabbedMode();
             finish();
             return;
         }
@@ -383,10 +383,9 @@
 
     /**
      * Handles launching a {@link ChromeTabbedActivity}.
-     * @param skipFre Whether skip the First Run Experience in ChromeTabbedActivity.
      */
     @SuppressLint("InlinedApi")
-    private void launchTabbedMode(boolean skipFre) {
+    private void launchTabbedMode() {
         maybePrefetchDnsInBackground();
 
         Intent newIntent = new Intent(getIntent());
@@ -406,9 +405,6 @@
         if (mIsInLegacyMultiInstanceMode) {
             MultiWindowUtils.getInstance().makeLegacyMultiInstanceIntent(this, newIntent);
         }
-        if (skipFre) {
-            newIntent.putExtra(FirstRunFlowSequencer.SKIP_FIRST_RUN_EXPERIENCE, true);
-        }
 
         // This system call is often modified by OEMs and not actionable. http://crbug.com/619646.
         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
index b0733e29..3de96e67 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunFlowSequencer.java
@@ -45,11 +45,6 @@
  * }.start();
  */
 public abstract class FirstRunFlowSequencer  {
-    /**
-     * Sending an intent with this extra will skip the First Run Experience.
-     */
-    public static final String SKIP_FIRST_RUN_EXPERIENCE = "skip_first_run_experience";
-
     private static final int FIRST_RUN_EXPERIENCE_REQUEST_CODE = 101;
     private static final String TAG = "firstrun";
 
@@ -274,10 +269,6 @@
             return null;
         }
 
-        if (fromIntent != null && fromIntent.getBooleanExtra(SKIP_FIRST_RUN_EXPERIENCE, false)) {
-            return null;
-        }
-
         // If Chrome isn't opened via the Chrome icon, and the user accepted the ToS
         // in the Setup Wizard, skip any First Run Experience screens and proceed directly
         // to the intent handling.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/DeletedPageInfo.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/DeletedPageInfo.java
new file mode 100644
index 0000000..5bc2ea40
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/DeletedPageInfo.java
@@ -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.
+
+package org.chromium.chrome.browser.offlinepages;
+
+/**
+ * Simple object representing important information of a deleted offline page.
+ */
+public class DeletedPageInfo {
+    private final long mOfflineId;
+    private final ClientId mClientId;
+    private final String mRequestOrigin;
+
+    public DeletedPageInfo(
+            long offlineId, String clientNamespace, String clientId, String requestOrigin) {
+        this(offlineId, new ClientId(clientNamespace, clientId), requestOrigin);
+    }
+
+    public DeletedPageInfo(long offlineId, ClientId clientId, String requestOrigin) {
+        mOfflineId = offlineId;
+        mClientId = clientId;
+        mRequestOrigin = requestOrigin;
+    }
+
+    /** @return offline id for the deleted page */
+    public long getOfflineId() {
+        return mOfflineId;
+    }
+
+    /** @return Client Id for the deleted page */
+    public ClientId getClientId() {
+        return mClientId;
+    }
+
+    /** @return request origin of the deleted page */
+    public String getRequestOrigin() {
+        return mRequestOrigin;
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
index e1c8b93..c2f25be 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java
@@ -94,7 +94,7 @@
          * @param offlineId The offline ID of the deleted offline page.
          * @param clientId The client supplied ID of the deleted offline page.
          */
-        public void offlinePageDeleted(long offlineId, ClientId clientId) {}
+        public void offlinePageDeleted(DeletedPageInfo deletedPage) {}
     }
 
     /**
@@ -568,9 +568,9 @@
     }
 
     @CalledByNative
-    void offlinePageDeleted(long offlineId, ClientId clientId) {
+    void offlinePageDeleted(DeletedPageInfo deletedPage) {
         for (OfflinePageModelObserver observer : mObservers) {
-            observer.offlinePageDeleted(offlineId, clientId);
+            observer.offlinePageDeleted(deletedPage);
         }
     }
 
@@ -595,6 +595,12 @@
         return new ClientId(clientNamespace, id);
     }
 
+    @CalledByNative
+    private static DeletedPageInfo createDeletedPageInfo(
+            long offlineId, String clientNamespace, String clientId, String requestOrigin) {
+        return new DeletedPageInfo(offlineId, clientNamespace, clientId, requestOrigin);
+    }
+
     private static native boolean nativeIsOfflineBookmarksEnabled();
     private static native boolean nativeIsPageSharingEnabled();
     private static native boolean nativeCanSavePage(String url);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SpannableAutocompleteEditTextModel.java b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SpannableAutocompleteEditTextModel.java
index 50148e73..90dcd90 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SpannableAutocompleteEditTextModel.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/omnibox/SpannableAutocompleteEditTextModel.java
@@ -361,13 +361,19 @@
 
         private boolean incrementBatchEditCount() {
             ++mBatchEditNestCount;
+            // After the outermost super.beginBatchEdit(), EditText will stop selection change
+            // update to the IME app.
             return super.beginBatchEdit();
         }
 
         private boolean decrementBatchEditCount() {
             --mBatchEditNestCount;
             boolean retVal = super.endBatchEdit();
-            if (mBatchEditNestCount == 0) updateSelectionForTesting();
+            if (mBatchEditNestCount == 0) {
+                // At the outermost super.endBatchEdit(), EditText will resume selection change
+                // update to the IME app.
+                updateSelectionForTesting();
+            }
             return retVal;
         }
 
@@ -385,13 +391,20 @@
 
         @Override
         public boolean beginBatchEdit() {
+            if (DEBUG) Log.i(TAG, "beginBatchEdit");
+            onBeginImeCommand();
             boolean retVal = incrementBatchEditCount();
-            // Note: this should be called after super.beginBatchEdit() to be effective.
+            onEndImeCommand();
+            return retVal;
+        }
+
+        private boolean onBeginImeCommand() {
+            if (DEBUG) Log.i(TAG, "onBeginImeCommand: " + mBatchEditNestCount);
+            boolean retVal = incrementBatchEditCount();
             if (mBatchEditNestCount == 1) {
-                if (DEBUG) Log.i(TAG, "beginBatchEdit");
                 mPreBatchEditState.copyFrom(mCurrentState);
-                mSpanController.removeSpan();
             }
+            mSpanController.removeSpan();
             return retVal;
         }
 
@@ -404,7 +417,6 @@
         }
 
         private boolean setAutocompleteSpan() {
-            assert mBatchEditNestCount == 1;
             mSpanController.removeSpan();
             if (DEBUG) {
                 Log.i(TAG, "setAutocompleteSpan. %s->%s", mPreviouslySetState, mCurrentState);
@@ -421,10 +433,20 @@
 
         @Override
         public boolean endBatchEdit() {
+            if (DEBUG) Log.i(TAG, "endBatchEdit");
+            onBeginImeCommand();
+            boolean retVal = decrementBatchEditCount();
+            onEndImeCommand();
+            return retVal;
+        }
+
+        private boolean onEndImeCommand() {
+            if (DEBUG) Log.i(TAG, "onEndImeCommand: " + (mBatchEditNestCount - 1));
             if (mBatchEditNestCount > 1) {
+                String diff = mCurrentState.getBackwardDeletedTextFrom(mPreBatchEditState);
+                if (diff == null) setAutocompleteSpan();
                 return decrementBatchEditCount();
             }
-            if (DEBUG) Log.i(TAG, "endBatchEdit");
 
             String diff = mCurrentState.getBackwardDeletedTextFrom(mPreBatchEditState);
             if (diff != null) {
@@ -458,109 +480,109 @@
         @Override
         public boolean commitText(CharSequence text, int newCursorPosition) {
             if (DEBUG) Log.i(TAG, "commitText: " + text);
-            beginBatchEdit();
+            onBeginImeCommand();
             boolean retVal = super.commitText(text, newCursorPosition);
-            endBatchEdit();
+            onEndImeCommand();
             return retVal;
         }
 
         @Override
         public boolean setComposingText(CharSequence text, int newCursorPosition) {
             if (DEBUG) Log.i(TAG, "setComposingText: " + text);
-            beginBatchEdit();
+            onBeginImeCommand();
             boolean retVal = super.setComposingText(text, newCursorPosition);
-            endBatchEdit();
+            onEndImeCommand();
             return retVal;
         }
 
         @Override
         public boolean setComposingRegion(int start, int end) {
             if (DEBUG) Log.i(TAG, "setComposingRegion: [%d,%d]", start, end);
-            beginBatchEdit();
+            onBeginImeCommand();
             boolean retVal = super.setComposingRegion(start, end);
-            endBatchEdit();
+            onEndImeCommand();
             return retVal;
         }
 
         @Override
         public boolean finishComposingText() {
             if (DEBUG) Log.i(TAG, "finishComposingText");
-            beginBatchEdit();
+            onBeginImeCommand();
             boolean retVal = super.finishComposingText();
-            endBatchEdit();
+            onEndImeCommand();
             return retVal;
         }
 
         @Override
         public boolean deleteSurroundingText(final int beforeLength, final int afterLength) {
             if (DEBUG) Log.i(TAG, "deleteSurroundingText [%d,%d]", beforeLength, afterLength);
-            beginBatchEdit();
+            onBeginImeCommand();
             boolean retVal = super.deleteSurroundingText(beforeLength, afterLength);
-            endBatchEdit();
+            onEndImeCommand();
             return retVal;
         }
 
         @Override
         public boolean setSelection(final int start, final int end) {
             if (DEBUG) Log.i(TAG, "setSelection [%d,%d]", start, end);
-            beginBatchEdit();
+            onBeginImeCommand();
             boolean retVal = super.setSelection(start, end);
-            endBatchEdit();
+            onEndImeCommand();
             return retVal;
         }
 
         @Override
         public boolean performEditorAction(final int editorAction) {
             if (DEBUG) Log.i(TAG, "performEditorAction: " + editorAction);
-            beginBatchEdit();
+            onBeginImeCommand();
             commitAutocomplete();
             boolean retVal = super.performEditorAction(editorAction);
-            endBatchEdit();
+            onEndImeCommand();
             return retVal;
         }
 
         @Override
         public boolean sendKeyEvent(final KeyEvent event) {
             if (DEBUG) Log.i(TAG, "sendKeyEvent: " + event.getKeyCode());
-            beginBatchEdit();
+            onBeginImeCommand();
             boolean retVal = super.sendKeyEvent(event);
-            endBatchEdit();
+            onEndImeCommand();
             return retVal;
         }
 
         @Override
         public ExtractedText getExtractedText(final ExtractedTextRequest request, final int flags) {
             if (DEBUG) Log.i(TAG, "getExtractedText");
-            beginBatchEdit();
+            onBeginImeCommand();
             ExtractedText retVal = super.getExtractedText(request, flags);
-            endBatchEdit();
+            onEndImeCommand();
             return retVal;
         }
 
         @Override
         public CharSequence getTextAfterCursor(final int n, final int flags) {
             if (DEBUG) Log.i(TAG, "getTextAfterCursor");
-            beginBatchEdit();
+            onBeginImeCommand();
             CharSequence retVal = super.getTextAfterCursor(n, flags);
-            endBatchEdit();
+            onEndImeCommand();
             return retVal;
         }
 
         @Override
         public CharSequence getTextBeforeCursor(final int n, final int flags) {
             if (DEBUG) Log.i(TAG, "getTextBeforeCursor");
-            beginBatchEdit();
+            onBeginImeCommand();
             CharSequence retVal = super.getTextBeforeCursor(n, flags);
-            endBatchEdit();
+            onEndImeCommand();
             return retVal;
         }
 
         @Override
         public CharSequence getSelectedText(final int flags) {
             if (DEBUG) Log.i(TAG, "getSelectedText");
-            beginBatchEdit();
+            onBeginImeCommand();
             CharSequence retVal = super.getSelectedText(flags);
-            endBatchEdit();
+            onEndImeCommand();
             return retVal;
         }
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/printing/TabPrinter.java b/chrome/android/java/src/org/chromium/chrome/browser/printing/TabPrinter.java
index fdb6879..ca66ebe 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/printing/TabPrinter.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/printing/TabPrinter.java
@@ -33,13 +33,13 @@
     }
 
     @Override
-    public boolean print() {
+    public boolean print(int renderProcessId, int renderFrameId) {
         Tab tab = mTab.get();
         if (tab == null || !tab.isInitialized()) {
             Log.d(TAG, "Tab not ready, unable to start printing.");
             return false;
         }
-        return tab.print();
+        return tab.print(renderProcessId, renderFrameId);
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsOfflineModelObserver.java b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsOfflineModelObserver.java
index 9cfb5bf..6d8a102c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsOfflineModelObserver.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/suggestions/SuggestionsOfflineModelObserver.java
@@ -7,7 +7,7 @@
 import android.support.annotation.Nullable;
 
 import org.chromium.base.Callback;
-import org.chromium.chrome.browser.offlinepages.ClientId;
+import org.chromium.chrome.browser.offlinepages.DeletedPageInfo;
 import org.chromium.chrome.browser.offlinepages.OfflinePageBridge;
 import org.chromium.chrome.browser.offlinepages.OfflinePageItem;
 
@@ -46,13 +46,13 @@
     }
 
     @Override
-    public void offlinePageDeleted(long offlineId, ClientId clientId) {
+    public void offlinePageDeleted(DeletedPageInfo deletedPage) {
         for (T suggestion : getOfflinableSuggestions()) {
             if (suggestion.requiresExactOfflinePage()) continue;
 
             Long suggestionOfflineId = suggestion.getOfflinePageOfflineId();
             if (suggestionOfflineId == null) continue;
-            if (suggestionOfflineId != offlineId) continue;
+            if (suggestionOfflineId != deletedPage.getOfflineId()) continue;
 
             // The old value cannot be simply removed without a request to the
             // model, because there may be an older offline page for the same
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
index 1c1d0ae..0f5a9fd 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/Tab.java
@@ -832,18 +832,18 @@
      *
      * @return Whether the printing process is started successfully.
      **/
-    public boolean print() {
+    public boolean print(int renderProcessId, int renderFrameId) {
         assert mNativeTabAndroid != 0;
-        return nativePrint(mNativeTabAndroid);
+        return nativePrint(mNativeTabAndroid, renderProcessId, renderFrameId);
     }
 
     @CalledByNative
-    public void setPendingPrint() {
+    public void setPendingPrint(int renderProcessId, int renderFrameId) {
         PrintingController printingController = PrintingControllerImpl.getInstance();
         if (printingController == null) return;
 
         printingController.setPendingPrint(new TabPrinter(this),
-                new PrintManagerDelegateImpl(getActivity()));
+                new PrintManagerDelegateImpl(getActivity()), renderProcessId, renderFrameId);
     }
 
     /**
@@ -1778,7 +1778,8 @@
                 @Override
                 public void run() {
                     if (showSendFeedbackView) {
-                        getActivity().startHelpAndFeedback(Tab.this, "MobileSadTabFeedback");
+                        getActivity().startHelpAndFeedback(
+                                getUrl(), "MobileSadTabFeedback", getProfile());
                     } else {
                         reload();
                     }
@@ -2509,6 +2510,11 @@
             mFullscreenManager.setPersistentFullscreenMode(enableFullscreen);
         }
 
+        // When going into fullscreen, we want to remove any cached thumbnail of the Tab.
+        if (enableFullscreen && mNativeTabAndroid != 0) {
+            nativeClearThumbnailPlaceholder(mNativeTabAndroid);
+        }
+
         RewindableIterator<TabObserver> observers = getTabObservers();
         while (observers.hasNext()) {
             observers.next().onToggleFullscreenMode(this, enableFullscreen);
@@ -3121,7 +3127,8 @@
             long intentReceivedTimestamp, boolean hasUserGesture);
     private native void nativeSetActiveNavigationEntryTitleForUrl(long nativeTabAndroid, String url,
             String title);
-    private native boolean nativePrint(long nativeTabAndroid);
+    private native boolean nativePrint(
+            long nativeTabAndroid, int renderProcessId, int renderFrameId);
     private native Bitmap nativeGetFavicon(long nativeTabAndroid);
     private native void nativeCreateHistoricalTab(long nativeTabAndroid);
     private native void nativeUpdateBrowserControlsState(
@@ -3132,6 +3139,7 @@
             InterceptNavigationDelegate delegate);
     private native void nativeAttachToTabContentManager(long nativeTabAndroid,
             TabContentManager tabContentManager);
+    private native void nativeClearThumbnailPlaceholder(long nativeTabAndroid);
     private native boolean nativeHasPrerenderedUrl(long nativeTabAndroid, String url);
     private native void nativeSetWebappManifestScope(long nativeTabAndroid, String scope);
     private native void nativeEnableEmbeddedMediaExperience(long nativeTabAndroid, boolean enabled);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java
index b6fe6ce7..4e03adf 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/BottomToolbarPhone.java
@@ -55,6 +55,7 @@
         @Override
         public void onSheetClosed() {
             onPrimaryColorChanged(true);
+            updateMenuButtonClickableState();
         }
 
         @Override
@@ -90,7 +91,7 @@
 
             boolean buttonsClickable = heightFraction == 0.f;
             mToggleTabStackButton.setClickable(buttonsClickable);
-            mMenuButton.setClickable(buttonsClickable);
+            updateMenuButtonClickableState();
             if (!mUseToolbarHandle) mExpandButton.setClickable(buttonsClickable);
         }
     };
@@ -129,9 +130,12 @@
     private TintedImageButton mExpandButton;
 
     /**
-     * Whether the toolbar buttons should be hidden regardless of whether the URL bar is focused.
+     * Whether some of the toolbar buttons are hidden regardless of whether the URL bar is focused.
+     * If {@link #mShowMenuButtonWhenSheetOpen} is false, all buttons are hidden.
+     * If {@link #mShowMenuButtonWhenSheetOpen} is true, all buttons besides the menu button are
+     * hidden.
      */
-    private boolean mShouldHideToolbarButtons;
+    private boolean mHidingSomeToolbarButtons;
 
     /**
      * This tracks the height fraction of the bottom bar to determine if it is moving up or down.
@@ -159,6 +163,9 @@
     /** Whether the disappearance of the toolbar buttons is currently animating. */
     private boolean mAnimatingToolbarButtonDisappearance;
 
+    /** Whether the menu button should be shown while the sheet is open. */
+    private boolean mShowMenuButtonWhenSheetOpen;
+
     /**
      * Constructs a BottomToolbarPhone object.
      * @param context The Context in which this View object is created.
@@ -371,19 +378,33 @@
         }
     }
 
+    private int getToolbarButtonsWidthForBackgroundOffset() {
+        return mShowMenuButtonWhenSheetOpen
+                ? mToolbarButtonsContainer.getMeasuredWidth() - mMenuButton.getMeasuredWidth()
+                : mToolbarButtonsContainer.getMeasuredWidth();
+    }
+
     private int getLocationBarBackgroundLeftOffset() {
         return !ApiCompatibilityUtils.isLayoutRtl(this)
                 ? 0
-                : mToolbarButtonsContainer.getMeasuredWidth() - mToolbarSidePadding;
+                : getToolbarButtonsWidthForBackgroundOffset() - mToolbarSidePadding;
     }
 
     private int getLocationBarBackgroundRightOffset() {
         return !ApiCompatibilityUtils.isLayoutRtl(this)
-                ? mToolbarButtonsContainer.getMeasuredWidth() - mToolbarSidePadding
+                ? getToolbarButtonsWidthForBackgroundOffset() - mToolbarSidePadding
                 : 0;
     }
 
     @Override
+    protected int getBoundsAfterAccountingForRightButtons() {
+        if (!mHidingSomeToolbarButtons) return super.getBoundsAfterAccountingForRightButtons();
+
+        return !mShowMenuButtonWhenSheetOpen ? mToolbarSidePadding
+                                             : mMenuButton.getMeasuredWidth() + mToolbarSidePadding;
+    }
+
+    @Override
     protected boolean isChildLeft(View child) {
         return (child == mNewTabButton || child == mExpandButton) ^ LocalizationUtils.isLayoutRtl();
     }
@@ -502,6 +523,12 @@
             ColorStateList tint = isIncognito() ? mLightModeTint : mDarkModeTint;
             mExpandButton.setTint(tint);
         }
+
+        if (mBottomSheet.isSheetOpen()) {
+            mShowMenuButtonWhenSheetOpen = mBottomSheet.isShowingNewTab();
+            updateButtonsContainerVisibilityAndTranslation();
+            updateMenuButtonClickableState();
+        }
     }
 
     @Override
@@ -591,8 +618,35 @@
     }
 
     @Override
-    protected boolean shouldHideToolbarButtons() {
-        return mShouldHideToolbarButtons;
+    protected int getToolbarButtonVisibility() {
+        if (mUrlExpansionPercent == 1f) return INVISIBLE;
+        if (mShowMenuButtonWhenSheetOpen) return VISIBLE;
+        if (mHidingSomeToolbarButtons) return INVISIBLE;
+        return VISIBLE;
+    }
+
+    @Override
+    protected float getUrlActionsTranslationXForExpansionAnimation(
+            boolean isLocationBarRtl, boolean isRtl, float locationBarBaseTranslationX) {
+        if (!mHidingSomeToolbarButtons) {
+            return super.getUrlActionsTranslationXForExpansionAnimation(
+                    isLocationBarRtl, isRtl, locationBarBaseTranslationX);
+        }
+
+        float urlActionsTranslationX = 0;
+        // When the end toolbar buttons are not hidden, URL actions are shown and hidden due to
+        // a change in location bar's width. When the end toolbar buttons are hidden, the
+        // location bar's width does not change by as much, causing the end location for the URL
+        // actions to be immediately visible. Translate the URL action container so that their
+        // appearance is animated.
+        float urlActionsTranslationXOffset =
+                mUrlActionContainer.getWidth() * (1 - mUrlExpansionPercent);
+        if (isLocationBarRtl) {
+            urlActionsTranslationX -= urlActionsTranslationXOffset;
+        } else {
+            urlActionsTranslationX += urlActionsTranslationXOffset;
+        }
+        return urlActionsTranslationX;
     }
 
     @Override
@@ -633,7 +687,7 @@
 
         if (mUrlFocusChangeInProgress) {
             if (visible) {
-                mShouldHideToolbarButtons = false;
+                mHidingSomeToolbarButtons = false;
                 mToolbarButtonVisibilityPercent = 1.f;
 
                 mToolbarButtonsContainer.setAlpha(1.f);
@@ -664,7 +718,8 @@
                 mAnimatingToolbarButtonAppearance = visible;
 
                 if (!visible) {
-                    mShouldHideToolbarButtons = true;
+                    mShowMenuButtonWhenSheetOpen = mBottomSheet.isShowingNewTab();
+                    mHidingSomeToolbarButtons = true;
                     mLayoutLocationBarInFocusedMode = true;
                     requestLayout();
                 } else {
@@ -684,9 +739,10 @@
             @Override
             public void onEnd(Animator animation) {
                 if (visible) {
-                    mShouldHideToolbarButtons = false;
+                    mHidingSomeToolbarButtons = false;
                     mDisableLocationBarRelayout = false;
                     mLayoutLocationBarInFocusedMode = false;
+                    mShowMenuButtonWhenSheetOpen = false;
                     requestLayout();
                 }
 
@@ -702,22 +758,16 @@
     @Override
     protected void onUrlFocusChangeAnimationFinished() {
         if (urlHasFocus()) {
-            mShouldHideToolbarButtons = true;
+            mHidingSomeToolbarButtons = true;
             mToolbarButtonVisibilityPercent = 0.f;
         }
+        updateMenuButtonClickableState();
     }
 
     private void updateToolbarButtonVisibility() {
         boolean isRtl = ApiCompatibilityUtils.isLayoutRtl(this);
-        float toolbarButtonsContainerWidth = mToolbarButtonsContainer.getMeasuredWidth();
-        float toolbarButtonsTranslationX =
-                toolbarButtonsContainerWidth * (1.f - mToolbarButtonVisibilityPercent);
-        if (isRtl) toolbarButtonsTranslationX *= -1;
 
-        mToolbarButtonsContainer.setTranslationX(toolbarButtonsTranslationX);
-        mToolbarButtonsContainer.setAlpha(mToolbarButtonVisibilityPercent);
-        mToolbarButtonsContainer.setVisibility(
-                mToolbarButtonVisibilityPercent > 0.f ? View.VISIBLE : View.INVISIBLE);
+        updateButtonsContainerVisibilityAndTranslation();
 
         float locationBarTranslationX;
         boolean isLocationBarRtl = ApiCompatibilityUtils.isLayoutRtl(mLocationBar);
@@ -759,4 +809,58 @@
         mLocationBar.invalidate();
         invalidate();
     }
+
+    /**
+     * Updates the visibility, alpha and translation of the buttons container based on
+     * {@link #mToolbarButtonVisibilityPercent}. If {@link #mShowMenuButtonWhenSheetOpen} is true,
+     * the tab switcher button and, if present, the expand button are faded out; nothing is
+     * translated. If {@link #mShowMenuButtonWhenSheetOpen} is false, the entire
+     * {@link #mToolbarButtonsContainer} is faded out and translated so that the buttons appear to
+     * slide off the toolbar.
+     */
+    private void updateButtonsContainerVisibilityAndTranslation() {
+        if (mShowMenuButtonWhenSheetOpen) {
+            mToolbarButtonsContainer.setTranslationX(0);
+            mToolbarButtonsContainer.setAlpha(1.f);
+            mToolbarButtonsContainer.setVisibility(View.VISIBLE);
+
+            float buttonAlpha = mToolbarButtonVisibilityPercent <= 0.5
+                    ? 0
+                    : 1.f - ((1.f - mToolbarButtonVisibilityPercent) * 2);
+            mToggleTabStackButton.setAlpha(buttonAlpha);
+            mToggleTabStackButton.setVisibility(
+                    mToolbarButtonVisibilityPercent > 0.f ? View.VISIBLE : View.INVISIBLE);
+
+            if (!mUseToolbarHandle) {
+                if (mTabSwitcherState != ENTERING_TAB_SWITCHER) mExpandButton.setAlpha(buttonAlpha);
+                mExpandButton.setVisibility(
+                        mToolbarButtonVisibilityPercent > 0.f ? View.VISIBLE : View.INVISIBLE);
+            }
+        } else {
+            mToggleTabStackButton.setAlpha(1.f);
+            mToggleTabStackButton.setVisibility(View.VISIBLE);
+
+            if (!mUseToolbarHandle) {
+                if (mTabSwitcherState != ENTERING_TAB_SWITCHER) mExpandButton.setAlpha(1.f);
+                mExpandButton.setVisibility(View.VISIBLE);
+            }
+
+            boolean isRtl = ApiCompatibilityUtils.isLayoutRtl(this);
+
+            float toolbarButtonsContainerWidth = mToolbarButtonsContainer.getMeasuredWidth();
+            float toolbarButtonsTranslationX =
+                    toolbarButtonsContainerWidth * (1.f - mToolbarButtonVisibilityPercent);
+            if (isRtl) toolbarButtonsTranslationX *= -1;
+
+            mToolbarButtonsContainer.setTranslationX(toolbarButtonsTranslationX);
+            mToolbarButtonsContainer.setAlpha(mToolbarButtonVisibilityPercent);
+            mToolbarButtonsContainer.setVisibility(
+                    mToolbarButtonVisibilityPercent > 0.f ? View.VISIBLE : View.INVISIBLE);
+        }
+    }
+
+    private void updateMenuButtonClickableState() {
+        mMenuButton.setClickable(
+                !urlHasFocus() && (!mBottomSheet.isSheetOpen() || mBottomSheet.isShowingNewTab()));
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
index 160b79c..273d26f 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarPhone.java
@@ -122,7 +122,7 @@
     protected NewTabButton mNewTabButton;
     private TintedImageButton mHomeButton;
     private TextView mUrlBar;
-    private View mUrlActionContainer;
+    protected View mUrlActionContainer;
     private ImageView mToolbarShadow;
 
     private final int mProgressBackBackgroundColorWhite;
@@ -679,8 +679,7 @@
      * @return The right bounds of the location bar after accounting for any visible left buttons.
      */
     protected int getBoundsAfterAccountingForRightButtons() {
-        return Math.max(mToolbarSidePadding,
-                shouldHideToolbarButtons() ? 0 : mToolbarButtonsContainer.getMeasuredWidth());
+        return Math.max(mToolbarSidePadding, mToolbarButtonsContainer.getMeasuredWidth());
     }
 
     protected void updateToolbarBackground(int color) {
@@ -848,10 +847,7 @@
             return;
         }
 
-        // Ensure the buttons are invisible after focusing the omnibox to prevent them from
-        // accepting click events.
-        int toolbarButtonVisibility =
-                mUrlExpansionPercent == 1f || shouldHideToolbarButtons() ? INVISIBLE : VISIBLE;
+        int toolbarButtonVisibility = getToolbarButtonVisibility();
         mToolbarButtonsContainer.setVisibility(toolbarButtonVisibility);
         if (mHomeButton.getVisibility() != GONE) {
             mHomeButton.setVisibility(toolbarButtonVisibility);
@@ -861,6 +857,13 @@
     }
 
     /**
+     * @return The visibility for {@link #mToolbarButtonsContainer}.
+     */
+    protected int getToolbarButtonVisibility() {
+        return mUrlExpansionPercent == 1f ? INVISIBLE : VISIBLE;
+    }
+
+    /**
      * Updates the location bar layout, as the result of either a focus change or scrolling the
      * New Tab Page.
      */
@@ -910,11 +913,32 @@
         }
 
         mLocationBar.setTranslationX(locationBarTranslationX);
+        mUrlActionContainer.setTranslationX(getUrlActionsTranslationXForExpansionAnimation(
+                isLocationBarRtl, isRtl, locationBarBaseTranslationX));
+        mLocationBar.setUrlFocusChangePercent(mUrlExpansionPercent);
 
-        // Negate the location bar translation to keep the URL action container in the same
-        // place during the focus expansion.
+        // Force an invalidation of the location bar to properly handle the clipping of the URL
+        // bar text as a result of the URL action container translations.
+        mLocationBar.invalidate();
+        invalidate();
+    }
+
+    /**
+     * Calculates the translation X for the URL actions container for use in the URL expansion
+     * animation.
+     *
+     * @param isLocationBarRtl Whether the location bar layout is RTL.
+     * @param isRtl Whether the toolbar layout is RTL.
+     * @param locationBarBaseTranslationX The base location bar translation for the URL expansion
+     *                                    animation.
+     * @return The translation X for the URL actions container.
+     */
+    protected float getUrlActionsTranslationXForExpansionAnimation(
+            boolean isLocationBarRtl, boolean isRtl, float locationBarBaseTranslationX) {
         float urlActionsTranslationX = 0;
         if (!isLocationBarRtl || isRtl) {
+            // Negate the location bar translation to keep the URL action container in the same
+            // place during the focus expansion.
             urlActionsTranslationX = -locationBarBaseTranslationX;
         }
 
@@ -924,29 +948,7 @@
             urlActionsTranslationX += mLocationBarNtpOffsetRight - mLocationBarNtpOffsetLeft;
         }
 
-        if (shouldHideToolbarButtons()) {
-            // When the end toolbar buttons are not hidden, url actions are shown and hidden due to
-            // a change in location bar's width. When the end toolbar buttons are hidden, the
-            // location bar's width does not change by as much, causing the end location for the url
-            // actions to be immediately visible. Translate the url action container so that their
-            // appearance is animated.
-            float urlActionsTranslationXOffset =
-                    mUrlActionContainer.getWidth() * (1 - mUrlExpansionPercent);
-            if (isLocationBarRtl) {
-                urlActionsTranslationX -= urlActionsTranslationXOffset;
-            } else {
-                urlActionsTranslationX += urlActionsTranslationXOffset;
-            }
-        }
-
-        mUrlActionContainer.setTranslationX(urlActionsTranslationX);
-
-        mLocationBar.setUrlFocusChangePercent(mUrlExpansionPercent);
-
-        // Force an invalidation of the location bar to properly handle the clipping of the URL
-        // bar text as a result of the url action container translations.
-        mLocationBar.invalidate();
-        invalidate();
+        return urlActionsTranslationX;
     }
 
     /**
@@ -1433,14 +1435,6 @@
         }
     }
 
-    /**
-     * @return Whether the toolbar buttons (tab switcher and menu) are currently hidden regardless
-     *         of URL bar focus. Sub-classes that hide these buttons should override this method.
-     */
-    protected boolean shouldHideToolbarButtons() {
-        return false;
-    }
-
     private ObjectAnimator createEnterTabSwitcherModeAnimation() {
         ObjectAnimator enterAnimation =
                 ObjectAnimator.ofFloat(this, mTabSwitcherModePercentProperty, 1.f);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrCancelAnimationActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrCancelAnimationActivity.java
new file mode 100644
index 0000000..1416c7f0
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrCancelAnimationActivity.java
@@ -0,0 +1,21 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.vr_shell;
+
+import android.app.Activity;
+import android.os.Bundle;
+
+/**
+ * Cancel the startActivity animation used to keep 2D UI hidden while Chrome is starting up.
+ * See the comments in VrShellDelegate.VrBroadcastReceiver#onReceive for more information.
+ */
+public class VrCancelAnimationActivity extends Activity {
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        finish();
+        overridePendingTransition(0, 0);
+    }
+}
\ No newline at end of file
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
index 69032c5..56541881 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellDelegate.java
@@ -136,6 +136,8 @@
     private final Handler mEnterVrHandler;
     private final Handler mExpectPauseOrDonSucceeded;
     private boolean mProbablyInDon;
+    private boolean mNeedsAnimationCancel;
+    private boolean mCancellingEntryAnimation;
 
     // Whether or not the VR Device ON flow succeeded. If this is true it means the user has a VR
     // headset on, but we haven't switched into VR mode yet.
@@ -196,13 +198,12 @@
                 // However, if we're already in VR (in one of the cases where we chose not to exit
                 // VR before the DON flow), we don't need to add the overlay.
                 if (!sInstance.mInVr) sInstance.addOverlayView();
+                sInstance.mNeedsAnimationCancel = !sInstance.mInVr;
 
-                // We start the Activity with a custom animation that keeps it hidden for a few
-                // hundred milliseconds - enough time for us to draw the first black view.
-                // TODO(mthiesse): This is really hacky. If we can find a way to cancel the
-                // transition animation (I couldn't), then we can just make it indefinite until the
-                // VR UI is ready, and then cancel it, rather than trying to guess how long it will
-                // take to draw the first view, and possibly adding latency to VR startup.
+                // We start the Activity with a custom animation that keeps it hidden while starting
+                // up to avoid Android showing stale 2D screenshots when the user is in their VR
+                // headset. The animation lasts up to 10 seconds, but is cancelled when we're
+                // resumed as at that time we'll be showing the black overlay added above.
                 int animation = sInstance.mInVr ? 0 : R.anim.stay_hidden;
                 Bundle options =
                         ActivityOptions.makeCustomAnimation(activity, animation, 0).toBundle();
@@ -591,6 +592,9 @@
             case ActivityState.STOPPED:
                 if (activity == mActivity) onStop();
                 break;
+            case ActivityState.STARTED:
+                if (activity == mActivity) onStart();
+                break;
             case ActivityState.RESUMED:
                 if (mInVr && activity != mActivity) {
                     if (mShowingDaydreamDoff) {
@@ -670,15 +674,7 @@
      */
     private boolean enterVrAfterDon() {
         if (mNativeVrShellDelegate == 0) return false;
-
-        // Normally, if the active page doesn't have a vrdisplayactivate listener, and WebVR was not
-        // presenting and VrShell was not enabled, the Daydream Homescreen should show after the DON
-        // flow. However, due to a failure in unregisterDaydreamIntent, we still try to enterVR, so
-        // detect this case and fail to enter VR.
-        if (!mListeningForWebVrActivateBeforePause && !mRequestedWebVr
-                && !canEnterVr(mActivity.getActivityTab())) {
-            return false;
-        }
+        if (!canEnterVr(mActivity.getActivityTab(), true)) return false;
 
         // If the page is listening for vrdisplayactivate we assume it wants to request
         // presentation. Go into WebVR mode tentatively. If the page doesn't request presentation
@@ -710,6 +706,7 @@
             cancelPendingVrEntry();
             return;
         }
+        mVrClassesWrapper.setVrModeEnabled(mActivity, true);
         if (!isWindowModeCorrectForVr()) {
             setWindowModeForVr(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
             mEnterVrHandler.post(new Runnable() {
@@ -742,12 +739,11 @@
         mDonSucceeded = false;
         if (!createVrShell()) {
             maybeSetPresentResult(false, donSuceeded);
-            mVrDaydreamApi.launchVrHomescreen();
             cancelPendingVrEntry();
             mInVr = false;
+            mVrDaydreamApi.launchVrHomescreen();
             return;
         }
-        mVrClassesWrapper.setVrModeEnabled(mActivity, true);
         mShouldShowPageInfo = false;
         shutdownNonPresentingNativeContext();
 
@@ -773,6 +769,7 @@
         maybeSetPresentResult(true, donSuceeded);
         mVrShell.getContainer().setOnSystemUiVisibilityChangeListener(this);
         removeOverlayView();
+
         if (!donSuceeded && !mAutopresentWebVr && isDaydreamCurrentViewer()) {
             // TODO(mthiesse): This is a VERY dirty hack. We need to know whether or not entering VR
             // will trigger the DON flow, so that we can wait for it to complete before we let the
@@ -843,25 +840,21 @@
         clearVrModeWindowFlags();
     }
 
-    /* package */ boolean canEnterVr(Tab tab) {
-        if (!LibraryLoader.isInitialized()) {
-            return false;
-        }
+    /* package */ boolean canEnterVr(Tab tab, boolean justCompletedDon) {
+        if (!LibraryLoader.isInitialized()) return false;
         if (mVrSupportLevel == VR_NOT_AVAILABLE || mNativeVrShellDelegate == 0) return false;
+
         // If vr shell is not enabled and this is not a web vr request, then return false.
-        if (!isVrShellEnabled(mVrSupportLevel)
-                && !(mRequestedWebVr || mListeningForWebVrActivate)) {
-            return false;
-        }
+        boolean presenting = mRequestedWebVr || mListeningForWebVrActivate
+                || (justCompletedDon && mListeningForWebVrActivateBeforePause) || mAutopresentWebVr;
+        if (!isVrShellEnabled(mVrSupportLevel) && !presenting) return false;
+
         // TODO(mthiesse): When we have VR UI for opening new tabs, etc., allow VR Shell to be
         // entered without any current tabs.
-        if (tab == null) {
-            return false;
-        }
+        if (tab == null) return false;
+
         // For now we don't handle sad tab page. crbug.com/661609
-        if (tab.isShowingSadTab()) {
-            return false;
-        }
+        if (tab.isShowingSadTab()) return false;
         return true;
     }
 
@@ -892,11 +885,13 @@
      */
     @EnterVRResult
     private int enterVrInternal() {
+        if (mPaused) return ENTER_VR_CANCELLED;
         if (mInVr) return ENTER_VR_NOT_NECESSARY;
+
         // Update VR support level as it can change at runtime
         updateVrSupportLevel();
         if (mVrSupportLevel == VR_NOT_AVAILABLE) return ENTER_VR_CANCELLED;
-        if (!canEnterVr(mActivity.getActivityTab())) return ENTER_VR_CANCELLED;
+        if (!canEnterVr(mActivity.getActivityTab(), false)) return ENTER_VR_CANCELLED;
         enterVr(false);
         return ENTER_VR_REQUESTED;
     }
@@ -918,6 +913,14 @@
     }
 
     private void onResume() {
+        if (mNeedsAnimationCancel) {
+            mCancellingEntryAnimation = true;
+            Bundle options = ActivityOptions.makeCustomAnimation(mActivity, 0, 0).toBundle();
+            mActivity.startActivity(
+                    new Intent(mActivity, VrCancelAnimationActivity.class), options);
+            mNeedsAnimationCancel = false;
+            return;
+        }
         mPaused = false;
 
         updateVrSupportLevel();
@@ -956,6 +959,7 @@
         }
 
         if (mDonSucceeded) {
+            mCancellingEntryAnimation = false;
             handleDonFlowSuccess();
         } else if (mRestoreOrientation != null) {
             // This means the user backed out of the DON flow, and we won't be entering VR.
@@ -980,8 +984,9 @@
     }
 
     private void onPause() {
-        mExpectPauseOrDonSucceeded.removeCallbacksAndMessages(null);
         mPaused = true;
+        if (mCancellingEntryAnimation) return;
+        mExpectPauseOrDonSucceeded.removeCallbacksAndMessages(null);
         unregisterDaydreamIntent(mVrDaydreamApi);
         if (mVrSupportLevel == VR_NOT_AVAILABLE) return;
 
@@ -1003,8 +1008,18 @@
         mIsDaydreamCurrentViewer = null;
     }
 
+    private void onStart() {
+        if (mDonSucceeded) {
+            // We're about to enter VR, so set the VR Mode as early as possible to avoid screen
+            // brightness flickering while in the headset.
+            mVrClassesWrapper.setVrModeEnabled(mActivity, true);
+            setWindowModeForVr(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+        }
+    }
+
     private void onStop() {
         cancelPendingVrEntry();
+        assert !mCancellingEntryAnimation;
         // We defer pausing of VrShell until the app is stopped to keep head tracking working for
         // as long as possible while going to daydream home.
         if (mInVr) mVrShell.pause();
@@ -1103,7 +1118,7 @@
                 // UI which is suboptimal.
                 nativeDisplayActivate(mNativeVrShellDelegate);
             }
-        } else if (!canEnterVr(mActivity.getActivityTab())) {
+        } else if (!canEnterVr(mActivity.getActivityTab(), false)) {
             unregisterDaydreamIntent(mVrDaydreamApi);
         }
     }
@@ -1113,6 +1128,8 @@
         mEnterVrHandler.removeCallbacksAndMessages(null);
         mDonSucceeded = false;
         removeOverlayView();
+        mVrClassesWrapper.setVrModeEnabled(mActivity, false);
+        restoreWindowMode();
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
index 3b52a8a3..2fa3272 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/vr_shell/VrShellImpl.java
@@ -391,7 +391,7 @@
     private void swapToForegroundTab() {
         Tab tab = mActivity.getActivityTab();
         if (tab == mTab) return;
-        if (!mDelegate.canEnterVr(tab)) {
+        if (!mDelegate.canEnterVr(tab, false)) {
             forceExitVr();
             return;
         }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
index c2f76ec..c73dc37 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/widget/bottomsheet/BottomSheet.java
@@ -795,7 +795,7 @@
         for (BottomSheetObserver o : mObservers) o.onLoadUrl(params.getUrl());
 
         // Native page URLs in this context do not need to communicate with the tab.
-        if (NativePageFactory.isNativePageUrl(params.getUrl(), incognito)) {
+        if (NativePageFactory.isNativePageUrl(params.getUrl(), incognito) && !isShowingNtp) {
             return TabLoadStatus.PAGE_LOAD_FAILED;
         }
 
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index b22a7fc..20b7cec 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -682,6 +682,7 @@
   "java/src/org/chromium/chrome/browser/offlinepages/BackgroundSchedulerBridge.java",
   "java/src/org/chromium/chrome/browser/offlinepages/BackgroundSchedulerProcessor.java",
   "java/src/org/chromium/chrome/browser/offlinepages/ClientId.java",
+  "java/src/org/chromium/chrome/browser/offlinepages/DeletedPageInfo.java",
   "java/src/org/chromium/chrome/browser/offlinepages/OfflineBackgroundTask.java",
   "java/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridge.java",
   "java/src/org/chromium/chrome/browser/offlinepages/OfflinePageItem.java",
@@ -1159,6 +1160,7 @@
   "java/src/org/chromium/chrome/browser/util/PlatformUtil.java",
   "java/src/org/chromium/chrome/browser/util/UrlUtilities.java",
   "java/src/org/chromium/chrome/browser/util/ViewUtils.java",
+  "java/src/org/chromium/chrome/browser/vr_shell/VrCancelAnimationActivity.java",
   "java/src/org/chromium/chrome/browser/vr_shell/NonPresentingGvrContext.java",
   "java/src/org/chromium/chrome/browser/vr_shell/VrClassesWrapper.java",
   "java/src/org/chromium/chrome/browser/vr_shell/VrCoreVersionChecker.java",
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java
index 84b1de4..fcc099b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/WebShareTest.java
@@ -110,8 +110,8 @@
     public void testWebShareNoUserGesture() throws Exception {
         mActivityTestRule.loadUrl(mUrl);
         mActivityTestRule.runJavaScriptCodeInCurrentTab("initiate_share()");
-        Assert.assertEquals(
-                "Fail: SecurityError: Must be handling a user gesture to perform a share request.",
+        Assert.assertEquals("Fail: NotAllowedError: "
+                        + "Must be handling a user gesture to perform a share request.",
                 mUpdateWaiter.waitForUpdate());
     }
 
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeUnitTest.java
index 3fede53..fe5a1d260 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeUnitTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/offlinepages/OfflinePageBridgeUnitTest.java
@@ -82,9 +82,9 @@
         public long lastDeletedOfflineId;
         public ClientId lastDeletedClientId;
 
-        public void offlinePageDeleted(long offlineId, ClientId clientId) {
-            lastDeletedOfflineId = offlineId;
-            lastDeletedClientId = clientId;
+        public void offlinePageDeleted(DeletedPageInfo deletedPage) {
+            lastDeletedOfflineId = deletedPage.getOfflineId();
+            lastDeletedClientId = deletedPage.getClientId();
         }
     }
 
@@ -110,7 +110,7 @@
 
         ClientId testClientId = new ClientId(TEST_NAMESPACE, TEST_ID);
         long testOfflineId = 123;
-        mBridge.offlinePageDeleted(testOfflineId, testClientId);
+        mBridge.offlinePageDeleted(new DeletedPageInfo(testOfflineId, testClientId, ""));
         assertEquals(testOfflineId, observer1.lastDeletedOfflineId);
         assertEquals(testClientId, observer1.lastDeletedClientId);
         assertEquals(testOfflineId, observer2.lastDeletedOfflineId);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java
index a98f5d6..ba0c6ce 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/omnibox/AutocompleteEditTextTest.java
@@ -191,8 +191,13 @@
 
         // User types a space.
         assertTrue(mInputConnection.beginBatchEdit());
+        // We should still show the intermediate autocomplete text to the user even in the middle of
+        // a batch edit. Otherwise, the user may see flickering of autocomplete text.
+        assertEquals("hello world", mAutocomplete.getText().toString());
         assertTrue(mInputConnection.commitText(" ", 1));
+        assertEquals("hello world", mAutocomplete.getText().toString());
         assertFalse(mAutocomplete.shouldAutocomplete());
+        assertEquals("hello world", mAutocomplete.getText().toString());
 
         mInOrder.verifyNoMoreInteractions();
         assertTrue(mInputConnection.endBatchEdit());
@@ -281,8 +286,19 @@
 
         // User types a space.
         assertTrue(mInputConnection.beginBatchEdit());
+        // We should still show the intermediate autocomplete text to the user even in the middle of
+        // a batch edit. Otherwise, the user may see flickering of autocomplete text.
+        if (isUsingSpannableModel()) {
+            assertEquals("hello world", mAutocomplete.getText().toString());
+        }
         assertTrue(mInputConnection.finishComposingText());
+        if (isUsingSpannableModel()) {
+            assertEquals("hello world", mAutocomplete.getText().toString());
+        }
         assertTrue(mInputConnection.commitText(" ", 1));
+        if (isUsingSpannableModel()) {
+            assertEquals("hello world", mAutocomplete.getText().toString());
+        }
 
         mInOrder.verifyNoMoreInteractions();
         assertTrue(mInputConnection.endBatchEdit());
diff --git a/chrome/app/OWNERS b/chrome/app/OWNERS
index 0589fa2..e52e392 100644
--- a/chrome/app/OWNERS
+++ b/chrome/app/OWNERS
@@ -12,6 +12,7 @@
 per-file chromium_strings.grd=*
 per-file generated_resources.grd=*
 per-file google_chrome_strings.grd=*
+per-file md_extensions_strings.grdp=*
 
 per-file media_router_strings.grdp*=apacible@chromium.org
 per-file media_router_strings.grdp*=imcheng@chromium.org
diff --git a/chrome/app/android/DEPS b/chrome/app/android/DEPS
index 0e145c3..6a58d29 100644
--- a/chrome/app/android/DEPS
+++ b/chrome/app/android/DEPS
@@ -3,4 +3,8 @@
   "chrome_main_delegate_android.cc": [
     "+content/browser/media/android/browser_media_player_manager.h",
   ],
+  "chrome_jni_onload.cc": [
+    "+device/vr/features/features.h",
+    "+third_party/gvr-android-sdk"
+  ],
 }
\ No newline at end of file
diff --git a/chrome/app/android/chrome_jni_onload.cc b/chrome/app/android/chrome_jni_onload.cc
index 64310dc..f0f168d 100644
--- a/chrome/app/android/chrome_jni_onload.cc
+++ b/chrome/app/android/chrome_jni_onload.cc
@@ -5,20 +5,38 @@
 #include "chrome/app/android/chrome_jni_onload.h"
 
 #include "base/android/jni_android.h"
-#include "base/android/library_loader/library_loader_hooks.h"
+#include "base/android/jni_registrar.h"
+#include "base/android/jni_utils.h"
 #include "chrome/app/android/chrome_android_initializer.h"
-#include "chrome/browser/android/chrome_jni_registrar.h"
 #include "content/public/app/content_jni_onload.h"
+#include "device/vr/features/features.h"
+
+#if BUILDFLAG(ENABLE_VR)
+#include "third_party/gvr-android-sdk/display_synchronizer_jni.h"
+#include "third_party/gvr-android-sdk/gvr_api_jni.h"
+#include "third_party/gvr-android-sdk/native_callbacks_jni.h"
+#endif
 
 namespace android {
 
+// These VR native functions are not handled by the automatic registration, so
+// they are manually registered here.
+static base::android::RegistrationMethod kChromeRegisteredMethods[] = {
+#if BUILDFLAG(ENABLE_VR)
+    {"DisplaySynchronizer",
+     DisplaySynchronizer::RegisterDisplaySynchronizerNatives},
+    {"GvrApi", GvrApi::RegisterGvrApiNatives},
+    {"NativeCallbacks", NativeCallbacks::RegisterNativeCallbacksNatives},
+#endif
+};
+
 bool OnJNIOnLoadRegisterJNI(JNIEnv* env) {
   if (!content::android::OnJNIOnLoadRegisterJNI(env))
     return false;
-
-  if (base::android::GetLibraryProcessType(env) ==
-      base::android::PROCESS_BROWSER) {
-    return RegisterBrowserJNI(env);
+  // Register manually when on the browser process.
+  if (!base::android::IsSelectiveJniRegistrationEnabled(env)) {
+    return RegisterNativeMethods(env, kChromeRegisteredMethods,
+                                 arraysize(kChromeRegisteredMethods));
   }
   return true;
 }
diff --git a/chrome/app/chrome_main.cc b/chrome/app/chrome_main.cc
index ac8075b..d1c673a2 100644
--- a/chrome/app/chrome_main.cc
+++ b/chrome/app/chrome_main.cc
@@ -9,7 +9,6 @@
 #include "base/time/time.h"
 #include "build/build_config.h"
 #include "chrome/app/chrome_main_delegate.h"
-#include "chrome/browser/profiling_host/profiling_process_host.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/features.h"
 #include "content/public/app/content_main.h"
@@ -18,6 +17,7 @@
 #include "ui/gfx/switches.h"
 
 #if BUILDFLAG(ENABLE_OOP_HEAP_PROFILING)
+#include "chrome/browser/profiling_host/profiling_process_host.h"
 #include "chrome/common/profiling/memlog_sender.h"
 #include "chrome/profiling/profiling_main.h"
 #endif
diff --git a/chrome/app/md_extensions_strings.grdp b/chrome/app/md_extensions_strings.grdp
index 9e9c912..3212ab57 100644
--- a/chrome/app/md_extensions_strings.grdp
+++ b/chrome/app/md_extensions_strings.grdp
@@ -94,6 +94,12 @@
   <message name="IDS_MD_EXTENSIONS_LOAD_ERROR_RETRY" desc="The text on the button to retry loading an unpacked extension after a failed load.">
     Retry
   </message>
+  <message name="IDS_MD_EXTENSIONS_NO_INSTALLED_ITEMS" desc="The message shown to the user on the Extensions settings page when there are no extensions or apps installed.">
+    Find extensions and apps in the <ph name="BEGIN_LINK">&lt;a target="_blank" href="https://chrome.google.com/webstore/category/extensions"&gt;</ph>Chrome Web Store<ph name="END_LINK">&lt;/a&gt;<ex>&lt;/a&gt;</ex></ph>
+  </message>
+  <message name="IDS_MD_EXTENSIONS_NO_SEARCH_RESULTS" desc="The message shown to the user when a search on the Extensions settings page has no matching results.">
+    No search results found
+  </message>
   <message name="IDS_MD_EXTENSIONS_PACK_DIALOG_TITLE" desc="The title of the dialog to pack an extension.">
     Pack extension
   </message>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index 98885438c..c362678 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -1082,9 +1082,6 @@
     <message name="IDS_SETTINGS_EASY_UNLOCK_DESCRIPTION" desc="The text that describes what Easy Unlock does.">
       Your <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> can be unlocked with your Android phone.
     </message>
-    <message name="IDS_SETTINGS_EASY_UNLOCK_REQUIRE_PROXIMITY_LABEL" desc="The text label that describes the checkbox that controls whether the user's Android phone must be in close proximity to the Chromebook in order to unlock it..">
-      Only unlock this <ph name="DEVICE_TYPE">$1<ex>Chromebook</ex></ph> when your phone is within arm’s reach
-    </message>
     <message name="IDS_SETTINGS_EASY_UNLOCK_TURN_OFF" desc="The label of the button to disable Easy unlock on the settings page and the turn off Easy unlock dialog.">
       Turn off
     </message>
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index fa986845..964cf82d 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1091,6 +1091,14 @@
          kClientPlaceholdersForServerLoFiEnabled,
          arraysize(kClientPlaceholdersForServerLoFiEnabled), nullptr}};
 
+const FeatureEntry::Choice kAsyncImageDecodingChoices[] = {
+    {flags_ui::kGenericExperimentChoiceDefault, "", ""},
+    {flags_ui::kGenericExperimentChoiceEnabled,
+     cc::switches::kEnableCheckerImaging, ""},
+    {flags_ui::kGenericExperimentChoiceDisabled,
+     cc::switches::kDisableCheckerImaging, ""},
+};
+
 // RECORDING USER METRICS FOR FLAGS:
 // -----------------------------------------------------------------------------
 // The first line of the entry is the internal name.
@@ -1383,10 +1391,6 @@
      flag_descriptions::kAshEnableUnifiedDesktopName,
      flag_descriptions::kAshEnableUnifiedDesktopDescription, kOsCrOS,
      SINGLE_VALUE_TYPE(switches::kEnableUnifiedDesktop)},
-    {"enable-easy-unlock-proximity-detection",
-     flag_descriptions::kEasyUnlockProximityDetectionName,
-     flag_descriptions::kEasyUnlockProximityDetectionDescription, kOsCrOS,
-     SINGLE_VALUE_TYPE(proximity_auth::switches::kEnableProximityDetection)},
     {"enable-easy-unlock-bluetooth-low-energy-detection",
      flag_descriptions::kEasyUnlockBluetoothLowEnergyDiscoveryName,
      flag_descriptions::kEasyUnlockBluetoothLowEnergyDiscoveryDescription,
@@ -3167,6 +3171,10 @@
      SINGLE_DISABLE_VALUE_TYPE(switches::kDelayReloadStopButtonChange)},
 #endif  // TOOLKIT_VIEWS
 
+    {"enable-async-image-decoding", flag_descriptions::kAsyncImageDecodingName,
+     flag_descriptions::kAsyncImageDecodingDescription, kOsAll,
+     MULTI_VALUE_TYPE(kAsyncImageDecodingChoices)},
+
     // NOTE: Adding new command-line switches requires adding corresponding
     // entries to enum "LoginCustomFlags" in histograms/enums.xml. See note in
     // enums.xml and don't forget to run AboutFlagsHistogramTest unit test.
diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc
index 841bfda..f5718a0 100644
--- a/chrome/browser/android/chrome_jni_registrar.cc
+++ b/chrome/browser/android/chrome_jni_registrar.cc
@@ -182,22 +182,12 @@
 #include "components/spellcheck/spellcheck_build_features.h"
 #include "components/sync/android/sync_jni_registrar.h"
 #include "components/variations/android/component_jni_registrar.h"
-#include "device/vr/features/features.h"
 #include "printing/features/features.h"
 
 #if BUILDFLAG(ENABLE_PRINTING) && !BUILDFLAG(ENABLE_PRINT_PREVIEW)
 #include "printing/printing_context_android.h"
 #endif
 
-#if BUILDFLAG(ENABLE_VR)
-#include "chrome/browser/android/vr_shell/vr_core_info.h"
-#include "chrome/browser/android/vr_shell/vr_shell.h"
-#include "chrome/browser/android/vr_shell/vr_shell_delegate.h"
-#include "third_party/gvr-android-sdk/display_synchronizer_jni.h"
-#include "third_party/gvr-android-sdk/gvr_api_jni.h"
-#include "third_party/gvr-android-sdk/native_callbacks_jni.h"
-#endif
-
 #if BUILDFLAG(ENABLE_OFFLINE_PAGES_HARNESS)
 #include "chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.h"
 #endif
@@ -413,15 +403,6 @@
     {"UsbChooserDialogAndroid", UsbChooserDialogAndroid::Register},
     {"Variations", variations::android::RegisterVariations},
     {"VariationsSession", chrome::android::RegisterVariationsSession},
-#if BUILDFLAG(ENABLE_VR)
-    {"VrCoreInfo", vr_shell::RegisterVrCoreInfo},
-    {"VrShell", vr_shell::RegisterVrShell},
-    {"VrShellDelegate", vr_shell::RegisterVrShellDelegate},
-    {"DisplaySynchronizer",
-     DisplaySynchronizer::RegisterDisplaySynchronizerNatives},
-    {"GvrApi", GvrApi::RegisterGvrApiNatives},
-    {"NativeCallbacks", NativeCallbacks::RegisterNativeCallbacksNatives},
-#endif
     {"WarmupManager", RegisterWarmupManager},
     {"WebApkInstaller", WebApkInstaller::Register},
     {"WebApkUpdateManager", WebApkUpdateManager::Register},
diff --git a/chrome/browser/android/compositor/tab_content_manager.cc b/chrome/browser/android/compositor/tab_content_manager.cc
index 8b5e26c..2b8a1b0 100644
--- a/chrome/browser/android/compositor/tab_content_manager.cc
+++ b/chrome/browser/android/compositor/tab_content_manager.cc
@@ -290,9 +290,7 @@
   thumbnail_cache_->UpdateVisibleIds(priority_ids, primary_tab_id);
 }
 
-void TabContentManager::RemoveTabThumbnail(JNIEnv* env,
-                                           const JavaParamRef<jobject>& obj,
-                                           jint tab_id) {
+void TabContentManager::NativeRemoveTabThumbnail(int tab_id) {
   TabReadbackRequestMap::iterator readback_iter =
       pending_tab_readbacks_.find(tab_id);
   if (readback_iter != pending_tab_readbacks_.end())
@@ -300,6 +298,12 @@
   thumbnail_cache_->Remove(tab_id);
 }
 
+void TabContentManager::RemoveTabThumbnail(JNIEnv* env,
+                                           const JavaParamRef<jobject>& obj,
+                                           jint tab_id) {
+  NativeRemoveTabThumbnail(tab_id);
+}
+
 void TabContentManager::GetDecompressedThumbnail(
     JNIEnv* env,
     const JavaParamRef<jobject>& obj,
diff --git a/chrome/browser/android/compositor/tab_content_manager.h b/chrome/browser/android/compositor/tab_content_manager.h
index e5e7763f..0a6a0fd 100644
--- a/chrome/browser/android/compositor/tab_content_manager.h
+++ b/chrome/browser/android/compositor/tab_content_manager.h
@@ -92,6 +92,7 @@
                         const base::android::JavaParamRef<jobject>& obj,
                         const base::android::JavaParamRef<jintArray>& priority,
                         jint primary_tab_id);
+  void NativeRemoveTabThumbnail(int tab_id);
   void RemoveTabThumbnail(JNIEnv* env,
                           const base::android::JavaParamRef<jobject>& obj,
                           jint tab_id);
diff --git a/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.cc b/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.cc
index c2501a3..44f12bf 100644
--- a/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.cc
+++ b/chrome/browser/android/offline_pages/downloads/offline_page_download_bridge.cc
@@ -11,6 +11,7 @@
 #include "base/guid.h"
 #include "base/logging.h"
 #include "base/memory/ptr_util.h"
+#include "chrome/browser/android/download/download_controller_base.h"
 #include "chrome/browser/android/offline_pages/downloads/offline_page_infobar_delegate.h"
 #include "chrome/browser/android/offline_pages/downloads/offline_page_notification_bridge.h"
 #include "chrome/browser/android/offline_pages/offline_page_mhtml_archiver.h"
@@ -31,6 +32,8 @@
 #include "content/public/browser/download_manager.h"
 #include "content/public/browser/download_url_parameters.h"
 #include "content/public/browser/navigation_entry.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
 #include "content/public/browser/web_contents.h"
 #include "jni/OfflinePageDownloadBridge_jni.h"
 #include "net/base/filename_util.h"
@@ -263,6 +266,65 @@
     LOG(WARNING) << "ResumeRequestsContinuation has no valid coordinator.";
 }
 
+content::WebContents* GetWebContentsByFrameID(int render_process_id,
+                                              int render_frame_id) {
+  content::RenderFrameHost* render_frame_host =
+      content::RenderFrameHost::FromID(render_process_id, render_frame_id);
+  if (!render_frame_host)
+    return NULL;
+  return content::WebContents::FromRenderFrameHost(render_frame_host);
+}
+
+content::ResourceRequestInfo::WebContentsGetter GetWebContentsGetter(
+    content::WebContents* web_contents) {
+  // PlzNavigate: The FrameTreeNode ID should be used to access the WebContents.
+  int frame_tree_node_id = web_contents->GetMainFrame()->GetFrameTreeNodeId();
+  if (frame_tree_node_id != -1) {
+    return base::Bind(content::WebContents::FromFrameTreeNodeId,
+                      frame_tree_node_id);
+  }
+
+  // In other cases, use the RenderProcessHost ID + RenderFrameHost ID to get
+  // the WebContents.
+  return base::Bind(&GetWebContentsByFrameID,
+                    web_contents->GetRenderProcessHost()->GetID(),
+                    web_contents->GetMainFrame()->GetRoutingID());
+}
+
+void OnAcquireFileAccessPermissionDone(
+    const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
+    bool granted) {
+  if (!granted)
+    return;
+
+  content::WebContents* web_contents = web_contents_getter.Run();
+  if (!web_contents)
+    return;
+
+  GURL url = web_contents->GetLastCommittedURL();
+  if (url.is_empty())
+    return;
+
+  content::DownloadManager* dlm = content::BrowserContext::GetDownloadManager(
+      web_contents->GetBrowserContext());
+  std::unique_ptr<content::DownloadUrlParameters> dl_params(
+      content::DownloadUrlParameters::CreateForWebContentsMainFrame(
+          web_contents, url, NO_TRAFFIC_ANNOTATION_YET));
+
+  content::NavigationEntry* entry =
+      web_contents->GetController().GetLastCommittedEntry();
+  // |entry| should not be null since otherwise an empty URL is returned from
+  // calling GetLastCommittedURL and we should bail out earlier.
+  DCHECK(entry);
+  content::Referrer referrer =
+      content::Referrer::SanitizeForRequest(url, entry->GetReferrer());
+  dl_params->set_referrer(referrer);
+
+  dl_params->set_prefer_cache(true);
+  dl_params->set_prompt(false);
+  dlm->DownloadUrl(std::move(dl_params));
+}
+
 }  // namespace
 
 OfflinePageDownloadBridge::OfflinePageDownloadBridge(
@@ -351,24 +413,11 @@
   // If the page is not a HTML page, route to DownloadManager.
   if (!offline_pages::OfflinePageUtils::CanDownloadAsOfflinePage(
           url, web_contents->GetContentsMimeType())) {
-    content::DownloadManager* dlm = content::BrowserContext::GetDownloadManager(
-        web_contents->GetBrowserContext());
-    std::unique_ptr<content::DownloadUrlParameters> dl_params(
-        content::DownloadUrlParameters::CreateForWebContentsMainFrame(
-            web_contents, url, NO_TRAFFIC_ANNOTATION_YET));
-
-    content::NavigationEntry* entry =
-        web_contents->GetController().GetLastCommittedEntry();
-    // |entry| should not be null since otherwise an empty URL is returned from
-    // calling GetLastCommittedURL and we should bail out earlier.
-    DCHECK(entry);
-    content::Referrer referrer =
-        content::Referrer::SanitizeForRequest(url, entry->GetReferrer());
-    dl_params->set_referrer(referrer);
-
-    dl_params->set_prefer_cache(true);
-    dl_params->set_prompt(false);
-    dlm->DownloadUrl(std::move(dl_params));
+    content::ResourceRequestInfo::WebContentsGetter web_contents_getter =
+        GetWebContentsGetter(web_contents);
+    DownloadControllerBase::Get()->AcquireFileAccessPermission(
+        web_contents_getter,
+        base::Bind(&OnAcquireFileAccessPermissionDone, web_contents_getter));
     return;
   }
 
diff --git a/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc b/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc
index 6fc30a6..5755f67 100644
--- a/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc
+++ b/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.cc
@@ -267,8 +267,7 @@
     const OfflinePageItem& added_page) {}
 
 void OfflinePageEvaluationBridge::OfflinePageDeleted(
-    int64_t offline_id,
-    const ClientId& client_id) {}
+    const DeletedPageInfo& page_info) {}
 
 // Implement RequestCoordinator::Observer
 void OfflinePageEvaluationBridge::OnAdded(const SavePageRequest& request) {
diff --git a/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.h b/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.h
index 398196f..17df3b3 100644
--- a/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.h
+++ b/chrome/browser/android/offline_pages/evaluation/offline_page_evaluation_bridge.h
@@ -44,8 +44,7 @@
   void OfflinePageModelLoaded(OfflinePageModel* model) override;
   void OfflinePageAdded(OfflinePageModel* model,
                         const OfflinePageItem& added_page) override;
-  void OfflinePageDeleted(int64_t offline_id,
-                          const ClientId& client_id) override;
+  void OfflinePageDeleted(const DeletedPageInfo& page_info) override;
 
   // RequestCoordinator::Observer implementation.
   void OnAdded(const SavePageRequest& request) override;
diff --git a/chrome/browser/android/offline_pages/offline_page_bridge.cc b/chrome/browser/android/offline_pages/offline_page_bridge.cc
index 3c9e4ab3d..104e5f7 100644
--- a/chrome/browser/android/offline_pages/offline_page_bridge.cc
+++ b/chrome/browser/android/offline_pages/offline_page_bridge.cc
@@ -80,6 +80,16 @@
       offline_page.access_count, offline_page.last_access_time.ToJavaTime());
 }
 
+ScopedJavaLocalRef<jobject> ToJavaDeletedPageInfo(
+    JNIEnv* env,
+    const OfflinePageModel::DeletedPageInfo& deleted_page) {
+  return Java_OfflinePageBridge_createDeletedPageInfo(
+      env, deleted_page.offline_id,
+      ConvertUTF8ToJavaString(env, deleted_page.client_id.name_space),
+      ConvertUTF8ToJavaString(env, deleted_page.client_id.id),
+      ConvertUTF8ToJavaString(env, deleted_page.request_origin));
+}
+
 void CheckPagesExistOfflineCallback(
     const ScopedJavaGlobalRef<jobject>& j_callback_obj,
     const OfflinePageModel::CheckPagesExistOfflineResult& offline_pages) {
@@ -297,11 +307,11 @@
       env, java_ref_, ToJavaOfflinePageItem(env, added_page));
 }
 
-void OfflinePageBridge::OfflinePageDeleted(int64_t offline_id,
-                                           const ClientId& client_id) {
+void OfflinePageBridge::OfflinePageDeleted(
+    const OfflinePageModel::DeletedPageInfo& page_info) {
   JNIEnv* env = base::android::AttachCurrentThread();
-  Java_OfflinePageBridge_offlinePageDeleted(env, java_ref_, offline_id,
-                                            CreateClientId(env, client_id));
+  Java_OfflinePageBridge_offlinePageDeleted(
+      env, java_ref_, ToJavaDeletedPageInfo(env, page_info));
 }
 
 void OfflinePageBridge::CheckPagesExistOffline(
diff --git a/chrome/browser/android/offline_pages/offline_page_bridge.h b/chrome/browser/android/offline_pages/offline_page_bridge.h
index 49b8d5a..21283c61 100644
--- a/chrome/browser/android/offline_pages/offline_page_bridge.h
+++ b/chrome/browser/android/offline_pages/offline_page_bridge.h
@@ -42,8 +42,8 @@
   void OfflinePageModelLoaded(OfflinePageModel* model) override;
   void OfflinePageAdded(OfflinePageModel* model,
                         const OfflinePageItem& added_page) override;
-  void OfflinePageDeleted(int64_t offline_id,
-                          const ClientId& client_id) override;
+  void OfflinePageDeleted(
+      const OfflinePageModel::DeletedPageInfo& page_info) override;
 
   void CheckPagesExistOffline(
       JNIEnv* env,
diff --git a/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc b/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc
index 9e46292..1ed59913b 100644
--- a/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc
+++ b/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc
@@ -138,7 +138,8 @@
     page_added_count_++;
     all_pages_needs_updating_ = true;
   }
-  void OfflinePageDeleted(int64_t, const offline_pages::ClientId&) override {
+  void OfflinePageDeleted(
+      const OfflinePageModel::DeletedPageInfo& pageInfo) override {
     model_removed_count_++;
     all_pages_needs_updating_ = true;
   }
diff --git a/chrome/browser/android/tab_android.cc b/chrome/browser/android/tab_android.cc
index 005669d..6be546f2 100644
--- a/chrome/browser/android/tab_android.cc
+++ b/chrome/browser/android/tab_android.cc
@@ -566,23 +566,38 @@
     entry->SetTitle(title);
 }
 
-bool TabAndroid::Print(JNIEnv* env, const JavaParamRef<jobject>& obj) {
+bool TabAndroid::Print(JNIEnv* env,
+                       const JavaParamRef<jobject>& obj,
+                       jint render_process_id,
+                       jint render_frame_id) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+
   if (!web_contents())
     return false;
 
-  printing::PrintViewManagerBasic::CreateForWebContents(web_contents());
+  content::RenderFrameHost* rfh =
+      content::RenderFrameHost::FromID(render_process_id, render_frame_id);
+
+  if (!rfh)
+    rfh = printing::GetFrameToPrint(web_contents());
+
+  content::WebContents* contents =
+      content::WebContents::FromRenderFrameHost(rfh);
+
+  printing::PrintViewManagerBasic::CreateForWebContents(contents);
   printing::PrintViewManagerBasic* print_view_manager =
-      printing::PrintViewManagerBasic::FromWebContents(web_contents());
+      printing::PrintViewManagerBasic::FromWebContents(contents);
   if (!print_view_manager)
     return false;
 
-  print_view_manager->PrintNow(printing::GetFrameToPrint(web_contents()));
+  print_view_manager->PrintNow(rfh);
   return true;
 }
 
-void TabAndroid::SetPendingPrint() {
+void TabAndroid::SetPendingPrint(int render_process_id, int render_frame_id) {
   JNIEnv* env = base::android::AttachCurrentThread();
-  Java_Tab_setPendingPrint(env, weak_java_tab_.get(env));
+  Java_Tab_setPendingPrint(env, weak_java_tab_.get(env), render_process_id,
+                           render_frame_id);
 }
 
 ScopedJavaLocalRef<jobject> TabAndroid::GetFavicon(
@@ -801,6 +816,12 @@
     tab_content_manager_->AttachLiveLayer(GetAndroidId(), GetContentLayer());
 }
 
+void TabAndroid::ClearThumbnailPlaceholder(JNIEnv* env,
+                                           const JavaParamRef<jobject>& obj) {
+  if (tab_content_manager_)
+    tab_content_manager_->NativeRemoveTabThumbnail(GetAndroidId());
+}
+
 scoped_refptr<content::DevToolsAgentHost> TabAndroid::GetDevToolsAgentHost() {
   return devtools_host_;
 }
diff --git a/chrome/browser/android/tab_android.h b/chrome/browser/android/tab_android.h
index 40390ee..ae6bdce6 100644
--- a/chrome/browser/android/tab_android.h
+++ b/chrome/browser/android/tab_android.h
@@ -186,10 +186,13 @@
       const base::android::JavaParamRef<jobject>& obj,
       const base::android::JavaParamRef<jstring>& jurl,
       const base::android::JavaParamRef<jstring>& jtitle);
-  bool Print(JNIEnv* env, const base::android::JavaParamRef<jobject>& obj);
+  bool Print(JNIEnv* env,
+             const base::android::JavaParamRef<jobject>& obj,
+             jint render_process_id,
+             jint render_frame_id);
 
   // Sets the tab as content to be printed through JNI.
-  void SetPendingPrint();
+  void SetPendingPrint(int render_process_id, int render_frame_id);
 
   // Called to get default favicon of current tab, return null if no
   // favicon is avaliable for current tab.
@@ -228,6 +231,10 @@
       const base::android::JavaParamRef<jobject>& obj,
       const base::android::JavaParamRef<jobject>& jtab_content_manager);
 
+  void ClearThumbnailPlaceholder(
+      JNIEnv* env,
+      const base::android::JavaParamRef<jobject>& obj);
+
   bool HasPrerenderedUrl(JNIEnv* env,
                          const base::android::JavaParamRef<jobject>& obj,
                          const base::android::JavaParamRef<jstring>& url);
diff --git a/chrome/browser/android/vr_shell/BUILD.gn b/chrome/browser/android/vr_shell/BUILD.gn
index eeaa5b2..bdb99e0 100644
--- a/chrome/browser/android/vr_shell/BUILD.gn
+++ b/chrome/browser/android/vr_shell/BUILD.gn
@@ -61,6 +61,7 @@
     "//content/public/browser",
     "//content/public/common",
     "//device/gamepad",
+    "//device/geolocation/public/interfaces",
     "//device/vr",
     "//services/ui/public/cpp/gpu",
     "//ui/android",
diff --git a/chrome/browser/android/vr_shell/vr_core_info.cc b/chrome/browser/android/vr_shell/vr_core_info.cc
index 6f8b491..e4e724452 100644
--- a/chrome/browser/android/vr_shell/vr_core_info.cc
+++ b/chrome/browser/android/vr_shell/vr_core_info.cc
@@ -22,10 +22,6 @@
 // Native JNI methods
 // ----------------------------------------------------------------------------
 
-bool RegisterVrCoreInfo(JNIEnv* env) {
-  return RegisterNativesImpl(env);
-}
-
 jlong Init(JNIEnv* env,
            const JavaParamRef<jobject>& obj,
            jint major_version,
diff --git a/chrome/browser/android/vr_shell/vr_core_info.h b/chrome/browser/android/vr_shell/vr_core_info.h
index b52d4b9..922d774 100644
--- a/chrome/browser/android/vr_shell/vr_core_info.h
+++ b/chrome/browser/android/vr_shell/vr_core_info.h
@@ -31,8 +31,6 @@
              VrCoreCompatibility compatibility);
 };
 
-bool RegisterVrCoreInfo(JNIEnv* env);
-
 }  // namespace vr_shell
 
 #endif  // CHROME_BROWSER_ANDROID_VR_SHELL_VR_CORE_INFO_H_
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.cc b/chrome/browser/android/vr_shell/vr_gl_thread.cc
index 714d0b3..702182d 100644
--- a/chrome/browser/android/vr_shell/vr_gl_thread.cc
+++ b/chrome/browser/android/vr_shell/vr_gl_thread.cc
@@ -209,6 +209,12 @@
                             weak_scene_manager_, enabled));
 }
 
+void VrGLThread::SetLocationAccessIndicator(bool enabled) {
+  task_runner()->PostTask(
+      FROM_HERE, base::Bind(&vr::UiSceneManager::SetLocationAccessIndicator,
+                            weak_scene_manager_, enabled));
+}
+
 void VrGLThread::SetVideoCapturingIndicator(bool enabled) {
   task_runner()->PostTask(
       FROM_HERE, base::Bind(&vr::UiSceneManager::SetVideoCapturingIndicator,
diff --git a/chrome/browser/android/vr_shell/vr_gl_thread.h b/chrome/browser/android/vr_shell/vr_gl_thread.h
index 6026c13..75c5e77 100644
--- a/chrome/browser/android/vr_shell/vr_gl_thread.h
+++ b/chrome/browser/android/vr_shell/vr_gl_thread.h
@@ -83,6 +83,7 @@
   void SetScreenCapturingIndicator(bool enabled) override;
   void SetAudioCapturingIndicator(bool enabled) override;
   void SetBluetoothConnectedIndicator(bool enabled) override;
+  void SetLocationAccessIndicator(bool enabled) override;
   void SetIsExiting() override;
   void SetSplashScreenIcon(const SkBitmap& bitmap) override;
 
diff --git a/chrome/browser/android/vr_shell/vr_shell.cc b/chrome/browser/android/vr_shell/vr_shell.cc
index 478c2ed..a8279e0 100644
--- a/chrome/browser/android/vr_shell/vr_shell.cc
+++ b/chrome/browser/android/vr_shell/vr_shell.cc
@@ -45,12 +45,15 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/referrer.h"
+#include "content/public/common/service_manager_connection.h"
+#include "device/geolocation/public/interfaces/geolocation_config.mojom.h"
 #include "device/vr/android/gvr/cardboard_gamepad_data_fetcher.h"
 #include "device/vr/android/gvr/gvr_device.h"
 #include "device/vr/android/gvr/gvr_device_provider.h"
 #include "device/vr/android/gvr/gvr_gamepad_data_fetcher.h"
 #include "gpu/command_buffer/common/mailbox.h"
 #include "jni/VrShellImpl_jni.h"
+#include "services/service_manager/public/cpp/connector.h"
 #include "third_party/WebKit/public/platform/WebInputEvent.h"
 #include "ui/android/view_android.h"
 #include "ui/android/window_android.h"
@@ -72,7 +75,7 @@
 vr_shell::VrShell* g_instance;
 
 constexpr base::TimeDelta poll_media_access_interval_ =
-    base::TimeDelta::FromSecondsD(0.1);
+    base::TimeDelta::FromSecondsD(0.2);
 
 constexpr base::TimeDelta kExitVrDueToUnsupportedModeDelay =
     base::TimeDelta::FromSeconds(5);
@@ -188,10 +191,6 @@
   }
 }
 
-bool RegisterVrShell(JNIEnv* env) {
-  return RegisterNativesImpl(env);
-}
-
 VrShell::~VrShell() {
   DVLOG(1) << __FUNCTION__ << "=" << this;
   poll_capturing_media_task_.Cancel();
@@ -644,6 +643,12 @@
     if (web_contents->IsConnectedToBluetoothDevice())
       num_tabs_bluetooth_connected++;
   }
+  auto* connector =
+      content::ServiceManagerConnection::GetForProcess()->GetConnector();
+  connector->BindInterface("content_browser", &geolocation_config_);
+
+  geolocation_config_->IsHighAccuracyLocationBeingCaptured(
+      base::Bind(&VrShell::SetHighAccuracyLocation, base::Unretained(this)));
 
   bool is_capturing_audio = num_tabs_capturing_audio > 0;
   bool is_capturing_video = num_tabs_capturing_video > 0;
@@ -667,6 +672,13 @@
   }
 }
 
+void VrShell::SetHighAccuracyLocation(bool high_accuracy_location) {
+  if (high_accuracy_location == high_accuracy_location_)
+    return;
+  ui_->SetLocationAccessIndicator(high_accuracy_location);
+  high_accuracy_location_ = high_accuracy_location;
+}
+
 void VrShell::SetContentCssSize(float width, float height, float dpr) {
   JNIEnv* env = base::android::AttachCurrentThread();
   Java_VrShellImpl_setContentCssSize(env, j_vr_shell_.obj(), width, height,
diff --git a/chrome/browser/android/vr_shell/vr_shell.h b/chrome/browser/android/vr_shell/vr_shell.h
index f69f2b7..c92ea63 100644
--- a/chrome/browser/android/vr_shell/vr_shell.h
+++ b/chrome/browser/android/vr_shell/vr_shell.h
@@ -19,6 +19,7 @@
 #include "chrome/browser/vr/ui_interface.h"
 #include "chrome/browser/vr/ui_unsupported_mode.h"
 #include "content/public/browser/web_contents_observer.h"
+#include "device/geolocation/public/interfaces/geolocation_config.mojom.h"
 #include "device/vr/android/gvr/cardboard_gamepad_data_provider.h"
 #include "device/vr/android/gvr/gvr_delegate.h"
 #include "device/vr/android/gvr/gvr_gamepad_data_provider.h"
@@ -161,6 +162,7 @@
   void DoUiAction(const UiAction action,
                   const base::DictionaryValue* arguments);
 
+  void SetHighAccuracyLocation(bool high_accuracy_location);
   void SetContentCssSize(float width, float height, float dpr);
 
   void ContentFrameWasResized(bool width_changed);
@@ -235,6 +237,8 @@
   vr::UiInterface* ui_;
   std::unique_ptr<vr::ToolbarHelper> toolbar_;
 
+  device::mojom::GeolocationConfigPtr geolocation_config_;
+
   jobject content_surface_ = nullptr;
   bool taken_surface_ = false;
   base::CancelableClosure poll_capturing_media_task_;
@@ -242,6 +246,7 @@
   bool is_capturing_video_ = false;
   bool is_capturing_screen_ = false;
   bool is_bluetooth_connected_ = false;
+  bool high_accuracy_location_ = false;
 
   // Are we currently providing a gamepad factory to the gamepad manager?
   bool gvr_gamepad_source_active_ = false;
@@ -259,8 +264,6 @@
   DISALLOW_COPY_AND_ASSIGN(VrShell);
 };
 
-bool RegisterVrShell(JNIEnv* env);
-
 }  // namespace vr_shell
 
 #endif  // CHROME_BROWSER_ANDROID_VR_SHELL_VR_SHELL_H_
diff --git a/chrome/browser/android/vr_shell/vr_shell_delegate.cc b/chrome/browser/android/vr_shell/vr_shell_delegate.cc
index 1453d8e7..33605a50 100644
--- a/chrome/browser/android/vr_shell/vr_shell_delegate.cc
+++ b/chrome/browser/android/vr_shell/vr_shell_delegate.cc
@@ -245,10 +245,6 @@
 // Native JNI methods
 // ----------------------------------------------------------------------------
 
-bool RegisterVrShellDelegate(JNIEnv* env) {
-  return RegisterNativesImpl(env);
-}
-
 jlong Init(JNIEnv* env, const JavaParamRef<jobject>& obj) {
   return reinterpret_cast<intptr_t>(new VrShellDelegate(env, obj));
 }
diff --git a/chrome/browser/android/vr_shell/vr_shell_delegate.h b/chrome/browser/android/vr_shell/vr_shell_delegate.h
index e5ca2c4c..2c25d86 100644
--- a/chrome/browser/android/vr_shell/vr_shell_delegate.h
+++ b/chrome/browser/android/vr_shell/vr_shell_delegate.h
@@ -96,8 +96,6 @@
   DISALLOW_COPY_AND_ASSIGN(VrShellDelegate);
 };
 
-bool RegisterVrShellDelegate(JNIEnv* env);
-
 }  // namespace vr_shell
 
 #endif  // CHROME_BROWSER_ANDROID_VR_SHELL_VR_SHELL_DELEGATE_H_
diff --git a/chrome/browser/browsing_data/browsing_data_appcache_helper_unittest.cc b/chrome/browser/browsing_data/browsing_data_appcache_helper_unittest.cc
index 7b89c894..9f6e5eb 100644
--- a/chrome/browser/browsing_data/browsing_data_appcache_helper_unittest.cc
+++ b/chrome/browser/browsing_data/browsing_data_appcache_helper_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/bind_helpers.h"
 #include "base/macros.h"
 #include "base/stl_util.h"
+#include "base/test/scoped_task_environment.h"
 #include "build/build_config.h"
 #include "chrome/test/base/testing_profile.h"
 #include "content/public/test/test_browser_thread_bundle.h"
@@ -43,15 +44,19 @@
 class CannedBrowsingDataAppCacheHelperTest : public testing::Test {
  public:
   CannedBrowsingDataAppCacheHelperTest()
-      : thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD) {}
+      : scoped_task_environment_(
+            base::test::ScopedTaskEnvironment::MainThreadType::UI),
+        thread_bundle_(content::TestBrowserThreadBundle::REAL_IO_THREAD) {}
 
   void TearDown() override {
     // Make sure we run all pending tasks on IO thread before testing
     // profile is destructed.
     content::RunAllPendingInMessageLoop(content::BrowserThread::IO);
+    scoped_task_environment_.RunUntilIdle();
   }
 
  protected:
+  base::test::ScopedTaskEnvironment scoped_task_environment_;
   content::TestBrowserThreadBundle thread_bundle_;
   TestingProfile profile_;
 };
@@ -62,7 +67,7 @@
   GURL manifest3("http://example2.com/path2/manifest.xml");
 
   scoped_refptr<CannedBrowsingDataAppCacheHelper> helper(
-      new CannedBrowsingDataAppCacheHelper(&profile_));
+      new CannedBrowsingDataAppCacheHelper(profile_.GetOffTheRecordProfile()));
   helper->AddAppCache(manifest1);
   helper->AddAppCache(manifest2);
   helper->AddAppCache(manifest3);
@@ -93,7 +98,7 @@
   GURL manifest("http://example.com/manifest.xml");
 
   scoped_refptr<CannedBrowsingDataAppCacheHelper> helper(
-      new CannedBrowsingDataAppCacheHelper(&profile_));
+      new CannedBrowsingDataAppCacheHelper(profile_.GetOffTheRecordProfile()));
   helper->AddAppCache(manifest);
   helper->AddAppCache(manifest);
 
@@ -115,7 +120,7 @@
   GURL manifest("http://example.com/manifest.xml");
 
   scoped_refptr<CannedBrowsingDataAppCacheHelper> helper(
-      new CannedBrowsingDataAppCacheHelper(&profile_));
+      new CannedBrowsingDataAppCacheHelper(profile_.GetOffTheRecordProfile()));
 
   ASSERT_TRUE(helper->empty());
   helper->AddAppCache(manifest);
@@ -124,20 +129,13 @@
   ASSERT_TRUE(helper->empty());
 }
 
-// Flaky on linux. See crbug.com/740801.
-#if defined(OS_LINUX) || defined(OS_ANDROID)
-#define MAYBE_Delete DISABLED_Delete
-#else
-#define MAYBE_Delete Delete
-#endif
-
-TEST_F(CannedBrowsingDataAppCacheHelperTest, MAYBE_Delete) {
+TEST_F(CannedBrowsingDataAppCacheHelperTest, Delete) {
   GURL manifest1("http://example.com/manifest1.xml");
   GURL manifest2("http://foo.example.com/manifest2.xml");
   GURL manifest3("http://bar.example.com/manifest3.xml");
 
   scoped_refptr<CannedBrowsingDataAppCacheHelper> helper(
-      new CannedBrowsingDataAppCacheHelper(&profile_));
+      new CannedBrowsingDataAppCacheHelper(profile_.GetOffTheRecordProfile()));
 
   EXPECT_TRUE(helper->empty());
   helper->AddAppCache(manifest1);
@@ -156,7 +154,7 @@
   GURL manifest2("chrome-devtools://abcdefghijklmnopqrstuvwxyz/manifest.xml");
 
   scoped_refptr<CannedBrowsingDataAppCacheHelper> helper(
-      new CannedBrowsingDataAppCacheHelper(&profile_));
+      new CannedBrowsingDataAppCacheHelper(profile_.GetOffTheRecordProfile()));
 
   ASSERT_TRUE(helper->empty());
   helper->AddAppCache(manifest1);
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 91cace2..221f030 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -69,7 +69,6 @@
 #include "chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_io_data.h"
-#include "chrome/browser/profiling_host/profiling_process_host.h"
 #include "chrome/browser/renderer_host/chrome_navigation_ui_data.h"
 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
 #include "chrome/browser/renderer_host/pepper/chrome_browser_pepper_host_factory.h"
@@ -389,6 +388,10 @@
 #include "chrome/browser/media/cast_remoting_connector.h"
 #endif
 
+#if BUILDFLAG(ENABLE_OOP_HEAP_PROFILING)
+#include "chrome/browser/profiling_host/profiling_process_host.h"
+#endif
+
 #if BUILDFLAG(ENABLE_PRINTING)
 #include "components/printing/service/public/interfaces/pdf_compositor.mojom.h"
 #endif
@@ -1655,7 +1658,9 @@
   command_line->CopySwitchesFrom(browser_command_line, kCommonSwitchNames,
                                  arraysize(kCommonSwitchNames));
 #if BUILDFLAG(ENABLE_OOP_HEAP_PROFILING)
-  profiling::ProfilingProcessHost::AddSwitchesToChildCmdLine(command_line);
+  if (process_type != switches::kZygoteProcess) {
+    profiling::ProfilingProcessHost::AddSwitchesToChildCmdLine(command_line);
+  }
 #endif
 
   static const char* const kDinosaurEasterEggSwitches[] = {
diff --git a/chrome/browser/chromeos/arc/arc_session_manager.cc b/chrome/browser/chromeos/arc/arc_session_manager.cc
index 1bed59e..92cd72c1 100644
--- a/chrome/browser/chromeos/arc/arc_session_manager.cc
+++ b/chrome/browser/chromeos/arc/arc_session_manager.cc
@@ -492,8 +492,11 @@
       // Request to stop the ARC. |state_| will be set to STOPPED eventually.
       // TODO(yusukes): Always call RequestStop() with |true|.
       // We can actually remove the boolean parameter then.
-      arc_session_runner_->RequestStop(false);
+      // Set state before requesting the runner to stop in order to prevent the
+      // case when |OnSessionStopped| can be called inline and as result
+      // |state_| might be changed.
       state_ = State::STOPPING;
+      arc_session_runner_->RequestStop(false);
       break;
     case State::STOPPING:
       // Now ARC is stopping. Do nothing here.
@@ -584,14 +587,17 @@
   enable_requested_ = true;
 
   VLOG(1) << "ARC opt-in. Starting ARC session.";
-  RequestEnableImpl();
+
+  // |directly_started_| flag must be preserved during the internal ARC restart.
+  // So set it only when ARC is externally requested to start.
+  directly_started_ = RequestEnableImpl();
 }
 
 bool ArcSessionManager::IsPlaystoreLaunchRequestedForTesting() const {
   return playstore_launcher_.get();
 }
 
-void ArcSessionManager::RequestEnableImpl() {
+bool ArcSessionManager::RequestEnableImpl() {
   DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
   DCHECK(profile_);
   DCHECK(enable_requested_);
@@ -604,7 +610,7 @@
     // stopped) or ARC data removal is in progress, postpone the enabling
     // procedure.
     reenable_arc_ = true;
-    return;
+    return false;
   }
 
   oobe_start_ = IsOobeOptInActive();
@@ -628,7 +634,7 @@
     // Otherwise, be silent now. Users are notified when clicking ARC app icons.
     if (!start_arc_directly && !g_disable_ui_for_testing)
       arc::ShowArcMigrationGuideNotification(profile_);
-    return;
+    return false;
   }
 
   if (!pai_starter_ && !profile_->GetPrefs()->GetBoolean(prefs::kArcSignedIn) &&
@@ -647,10 +653,11 @@
     // Thus, StartArc() should be called so that disabling should work even
     // if synchronous call case.
     StartBackgroundAndroidManagementCheck();
-    return;
+    return true;
   }
 
   MaybeStartTermsOfServiceNegotiation();
+  return false;
 }
 
 void ArcSessionManager::RequestDisable() {
@@ -663,7 +670,9 @@
     arc_session_runner_->RequestStop(true);
     return;
   }
+
   oobe_start_ = false;
+  directly_started_ = false;
   enable_requested_ = false;
   scoped_opt_in_tracker_.reset();
 
@@ -945,7 +954,9 @@
 
 void ArcSessionManager::StopArc() {
   // TODO(hidehiko): This STOPPED guard should be unnecessary. Remove it later.
-  if (state_ != State::STOPPED) {
+  // |reenable_arc_| may be set in |StopAndEnableArc| in case enterprise
+  // management state is lost.
+  if (!reenable_arc_ && state_ != State::STOPPED) {
     profile_->GetPrefs()->SetBoolean(prefs::kArcSignedIn, false);
     profile_->GetPrefs()->SetBoolean(prefs::kArcTermsAccepted, false);
   }
diff --git a/chrome/browser/chromeos/arc/arc_session_manager.h b/chrome/browser/chromeos/arc/arc_session_manager.h
index caca575c..85f5f91d 100644
--- a/chrome/browser/chromeos/arc/arc_session_manager.h
+++ b/chrome/browser/chromeos/arc/arc_session_manager.h
@@ -245,6 +245,12 @@
   // available only on initial start.
   ArcPaiStarter* pai_starter() { return pai_starter_.get(); }
 
+  // Returns true if the current ARC run has started with skipping user ToS
+  // negotiation, because the user had accepted already or policy does not
+  // require ToS acceptance. Returns false in other cases, including one when
+  // ARC is not currently running.
+  bool is_directly_started() const { return directly_started_; }
+
   // Injectors for testing.
   void SetArcSessionRunnerForTesting(
       std::unique_ptr<ArcSessionRunner> arc_session_runner);
@@ -269,7 +275,8 @@
 
   // RequestEnable() has a check in order not to trigger starting procedure
   // twice. This method can be called to bypass that check when restarting.
-  void RequestEnableImpl();
+  // Returns true if ARC is started directly.
+  bool RequestEnableImpl();
 
   // Negotiates the terms of service to user, if necessary.
   // Otherwise, move to StartAndroidManagementCheck().
@@ -360,6 +367,7 @@
   // |IsOobeOptInActive| will be changed by the time when |oobe_start_| is
   // checked to prevent the Play Store auto-launch.
   bool oobe_start_ = false;
+  bool directly_started_ = false;
   base::OneShotTimer arc_sign_in_timer_;
 
   std::unique_ptr<ArcSupportHost> support_host_;
diff --git a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
index a9f7953..0efef9ad 100644
--- a/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
+++ b/chrome/browser/chromeos/arc/arc_session_manager_unittest.cc
@@ -486,6 +486,74 @@
   arc_session_manager()->Shutdown();
 }
 
+// Test case when directly started flag is not set during the ARC boot.
+TEST_F(ArcSessionManagerTest, IsDirectlyStartedFalse) {
+  arc_session_manager()->SetProfile(profile());
+  arc_session_manager()->Initialize();
+
+  // On initial start directy started flag is not set.
+  EXPECT_FALSE(arc_session_manager()->is_directly_started());
+  arc_session_manager()->RequestEnable();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(arc_session_manager()->is_directly_started());
+  ASSERT_EQ(ArcSessionManager::State::NEGOTIATING_TERMS_OF_SERVICE,
+            arc_session_manager()->state());
+  arc_session_manager()->OnTermsOfServiceNegotiatedForTesting(true);
+  arc_session_manager()->StartArcForTesting();
+  arc_session_manager()->OnProvisioningFinished(ProvisioningResult::SUCCESS);
+  EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
+  EXPECT_FALSE(arc_session_manager()->is_directly_started());
+  arc_session_manager()->Shutdown();
+  EXPECT_FALSE(arc_session_manager()->is_directly_started());
+}
+
+// Test case when directly started flag is set during the ARC boot.
+// Preconditions are: ToS accepted and ARC was signed in.
+TEST_F(ArcSessionManagerTest, IsDirectlyStartedTrue) {
+  PrefService* const prefs = profile()->GetPrefs();
+  prefs->SetBoolean(prefs::kArcTermsAccepted, true);
+  prefs->SetBoolean(prefs::kArcSignedIn, true);
+
+  arc_session_manager()->SetProfile(profile());
+  arc_session_manager()->Initialize();
+  EXPECT_FALSE(arc_session_manager()->is_directly_started());
+  arc_session_manager()->RequestEnable();
+  base::RunLoop().RunUntilIdle();
+  EXPECT_TRUE(arc_session_manager()->is_directly_started());
+  EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
+
+  // Disabling ARC turns directy started flag off.
+  arc_session_manager()->RequestDisable();
+  EXPECT_FALSE(arc_session_manager()->is_directly_started());
+  arc_session_manager()->Shutdown();
+}
+
+// Test case when directly started flag is preserved during the internal ARC
+// restart.
+TEST_F(ArcSessionManagerTest, IsDirectlyStartedOnInternalRestart) {
+  arc_session_manager()->SetProfile(profile());
+  arc_session_manager()->Initialize();
+  arc_session_manager()->RequestEnable();
+  base::RunLoop().RunUntilIdle();
+  ASSERT_EQ(ArcSessionManager::State::NEGOTIATING_TERMS_OF_SERVICE,
+            arc_session_manager()->state());
+  arc_session_manager()->OnTermsOfServiceNegotiatedForTesting(true);
+  arc_session_manager()->StartArcForTesting();
+  arc_session_manager()->OnProvisioningFinished(ProvisioningResult::SUCCESS);
+  EXPECT_FALSE(arc_session_manager()->is_directly_started());
+  EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
+  EXPECT_FALSE(arc_session_manager()->is_directly_started());
+
+  // Simualate internal restart.
+  arc_session_manager()->StopAndEnableArc();
+  // Fake ARC session implementation synchronously calls stop callback and
+  // session manager should be reactivated at this moment.
+  EXPECT_EQ(ArcSessionManager::State::ACTIVE, arc_session_manager()->state());
+  // directy started flag should be preserved.
+  EXPECT_FALSE(arc_session_manager()->is_directly_started());
+  arc_session_manager()->Shutdown();
+}
+
 class ArcSessionManagerArcAlwaysStartTest : public ArcSessionManagerTest {
  public:
   ArcSessionManagerArcAlwaysStartTest() = default;
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc
index a2ce9eb..efeeb788 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -678,6 +678,7 @@
 
 void UserSessionManager::DoBrowserLaunch(Profile* profile,
                                          LoginDisplayHost* login_host) {
+  ui_shown_time_ = base::Time::Now();
   DoBrowserLaunchInternal(profile, login_host, false /* locale_pref_checked */);
 }
 
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.h b/chrome/browser/chromeos/login/session/user_session_manager.h
index 3a853e3..592b842 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.h
+++ b/chrome/browser/chromeos/login/session/user_session_manager.h
@@ -13,6 +13,7 @@
 #include "base/memory/singleton.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
+#include "base/time/time.h"
 #include "chrome/browser/chromeos/base/locale_util.h"
 #include "chrome/browser/chromeos/eol_notification.h"
 #include "chrome/browser/chromeos/hats/hats_notification_controller.h"
@@ -250,6 +251,8 @@
   const UserContext& user_context() const { return user_context_; }
   bool has_auth_cookies() const { return has_auth_cookies_; }
 
+  const base::Time& ui_shown_time() const { return ui_shown_time_; }
+
   void Shutdown();
 
  private:
@@ -512,6 +515,9 @@
   // Child account status is necessary for InitializeStartUrls call.
   bool waiting_for_child_account_status_;
 
+  // If set then contains the time when UI is shown.
+  base::Time ui_shown_time_;
+
   scoped_refptr<HatsNotificationController> hats_notification_controller_;
 
   base::WeakPtrFactory<UserSessionManager> weak_factory_;
diff --git a/chrome/browser/chromeos/policy/variations_service_policy_browsertest.cc b/chrome/browser/chromeos/policy/variations_service_policy_browsertest.cc
index e4f479f7..0c0bdc7 100644
--- a/chrome/browser/chromeos/policy/variations_service_policy_browsertest.cc
+++ b/chrome/browser/chromeos/policy/variations_service_policy_browsertest.cc
@@ -11,7 +11,6 @@
 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
-#include "chrome/browser/metrics/variations/chrome_variations_service_client.h"
 #include "chrome/test/base/testing_browser_process.h"
 #include "components/variations/service/variations_service.h"
 #include "net/base/url_util.h"
@@ -21,7 +20,9 @@
 
 class VariationsServiceDevicePolicyTest : public DevicePolicyCrosBrowserTest {
  protected:
-  VariationsServiceDevicePolicyTest() {}
+  VariationsServiceDevicePolicyTest() {
+    variations::VariationsService::EnableForTesting();
+  }
 
   void SetUpInProcessBrowserTestFixture() override {
     DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture();
@@ -46,16 +47,10 @@
   const std::string default_variations_url =
       variations::VariationsService::GetDefaultVariationsServerURLForTesting();
 
-  // g_browser_process->variations_service() is null by default in Chromium
-  // builds, so construct a VariationsService locally instead.
-  std::unique_ptr<variations::VariationsService> service =
-      variations::VariationsService::CreateForTesting(
-          base::MakeUnique<ChromeVariationsServiceClient>(),
-          g_browser_process->local_state());
-
   // Device policy has updated the cros settings.
-  const GURL url = service->GetVariationsServerURL(
-      g_browser_process->local_state(), std::string());
+  const GURL url =
+      g_browser_process->variations_service()->GetVariationsServerURL(
+          g_browser_process->local_state(), std::string());
   EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url,
                                base::CompareCase::SENSITIVE));
   std::string value;
diff --git a/chrome/browser/chromeos/tether/tether_service.cc b/chrome/browser/chromeos/tether/tether_service.cc
index f7f9c8d..67a26ad 100644
--- a/chrome/browser/chromeos/tether/tether_service.cc
+++ b/chrome/browser/chromeos/tether/tether_service.cc
@@ -135,6 +135,8 @@
 
   shut_down_ = true;
 
+  // Remove all observers. This ensures that once Shutdown() is called, no more
+  // calls to UpdateTetherTechnologyState() will be triggered.
   power_manager_client_->RemoveObserver(this);
   session_manager_client_->RemoveObserver(this);
   cryptauth_service_->GetCryptAuthDeviceManager()->RemoveObserver(this);
@@ -143,7 +145,10 @@
     adapter_->RemoveObserver(this);
   registrar_.RemoveAll();
 
-  UpdateTetherTechnologyState();
+  // Shut down the feature. Note that this does not change Tether's technology
+  // state in NetworkStateHandler because doing so could cause visual jank just
+  // as the user logs out.
+  StopTether();
 }
 
 void TetherService::SuspendImminent() {
diff --git a/chrome/browser/chromeos/tether/tether_service_unittest.cc b/chrome/browser/chromeos/tether/tether_service_unittest.cc
index 76fdb5c..be4f0fa 100644
--- a/chrome/browser/chromeos/tether/tether_service_unittest.cc
+++ b/chrome/browser/chromeos/tether/tether_service_unittest.cc
@@ -233,10 +233,12 @@
 
   ShutdownTetherService();
 
-  EXPECT_EQ(
-      chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_UNAVAILABLE,
-      network_state_handler()->GetTechnologyState(
-          chromeos::NetworkTypePattern::Tether()));
+  // The TechnologyState should not have changed due to Shutdown() being called.
+  // If it had changed, any settings UI that was previously open would have
+  // shown visual jank.
+  EXPECT_EQ(chromeos::NetworkStateHandler::TechnologyState::TECHNOLOGY_ENABLED,
+            network_state_handler()->GetTechnologyState(
+                chromeos::NetworkTypePattern::Tether()));
   EXPECT_FALSE(test_initializer_delegate_->is_tether_running());
 }
 
diff --git a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
index 9e42d15..3b7dc3a 100644
--- a/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
+++ b/chrome/browser/extensions/api/easy_unlock_private/easy_unlock_private_api.cc
@@ -904,10 +904,6 @@
     user.logged_in = service->GetType() == EasyUnlockService::TYPE_REGULAR;
     user.data_ready = user.logged_in || service->GetRemoteDevices() != NULL;
 
-    EasyUnlockService::UserSettings user_settings =
-        EasyUnlockService::GetUserSettings(account_id);
-    user.require_close_proximity = user_settings.require_close_proximity;
-
     user.device_user_id = cryptauth::CalculateDeviceUserId(
         EasyUnlockService::GetDeviceId(), account_id.GetUserEmail());
 
diff --git a/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc b/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc
index aa8e682..902aa74 100644
--- a/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc
+++ b/chrome/browser/extensions/api/messaging/native_message_host_chromeos.cc
@@ -60,7 +60,7 @@
     if (request_string.find("stopHostTest") != std::string::npos) {
       client_->CloseChannel(kNativeHostExited);
     } else if (request_string.find("bigMessageTest") != std::string::npos) {
-      client_->CloseChannel(kHostInputOuputError);
+      client_->CloseChannel(kHostInputOutputError);
     } else {
       ProcessEcho(*request);
     }
diff --git a/chrome/browser/extensions/api/messaging/native_message_process_host.cc b/chrome/browser/extensions/api/messaging/native_message_process_host.cc
index 68842631..e4ab4bf 100644
--- a/chrome/browser/extensions/api/messaging/native_message_process_host.cc
+++ b/chrome/browser/extensions/api/messaging/native_message_process_host.cc
@@ -140,7 +140,8 @@
 
   process_ = std::move(process);
 #if defined(OS_POSIX)
-  // This object is not the owner of the file so it should not keep an fd.
+  // |read_stream_| will take ownership of |read_file|, so note the underlying
+  // file descript for use with FileDescriptorWatcher.
   read_file_ = read_file.GetPlatformFile();
 #endif
 
@@ -208,9 +209,11 @@
   // would always be consuming one thread in the thread pool. On Windows
   // FileStream uses overlapped IO, so that optimization isn't necessary there.
 #if defined(OS_POSIX)
-  read_controller_ = base::FileDescriptorWatcher::WatchReadable(
-      read_file_,
-      base::Bind(&NativeMessageProcessHost::DoRead, base::Unretained(this)));
+  if (!read_controller_) {
+    read_controller_ = base::FileDescriptorWatcher::WatchReadable(
+        read_file_,
+        base::Bind(&NativeMessageProcessHost::DoRead, base::Unretained(this)));
+  }
 #else  // defined(OS_POSIX)
   DoRead();
 #endif  // defined(!OS_POSIX)
@@ -219,10 +222,6 @@
 void NativeMessageProcessHost::DoRead() {
   DCHECK(task_runner_->BelongsToCurrentThread());
 
-#if defined(OS_POSIX)
-  read_controller_.reset();
-#endif
-
   while (!closed_ && !read_pending_) {
     read_buffer_ = new net::IOBuffer(kReadBufferSize);
     int result =
@@ -257,8 +256,7 @@
     // Posix read() returns 0 in that case.
     Close(kNativeHostExited);
   } else {
-    LOG(ERROR) << "Error when reading from Native Messaging host: " << result;
-    Close(kHostInputOuputError);
+    Close(kHostInputOutputError);
   }
 }
 
@@ -278,7 +276,7 @@
     if (message_size > kMaximumMessageSize) {
       LOG(ERROR) << "Native Messaging host tried sending a message that is "
                  << message_size << " bytes long.";
-      Close(kHostInputOuputError);
+      Close(kHostInputOutputError);
       return;
     }
 
@@ -322,7 +320,7 @@
       write_pending_ = true;
     } else {
       LOG(ERROR) << "Error when writing to Native Messaging host: " << result;
-      Close(kHostInputOuputError);
+      Close(kHostInputOutputError);
     }
     return;
   }
@@ -345,6 +343,9 @@
 
   if (!closed_) {
     closed_ = true;
+#if defined(OS_POSIX)
+    read_controller_.reset();
+#endif
     read_stream_.reset();
     write_stream_.reset();
     client_->CloseChannel(error_message);
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 3d506eb..36d07a3a 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -37,6 +37,10 @@
     "Enable the display of Progressive Web App banners, which prompt a user to "
     "add a web app to their shelf, or other platform-specific equivalent.";
 
+const char kAsyncImageDecodingName[] = "AsyncImageDecoding";
+const char kAsyncImageDecodingDescription[] =
+    "Enables asynchronous decoding of images from raster for web content";
+
 const char kAutoplayPolicyName[] = "Autoplay policy";
 const char kAutoplayPolicyDescription[] =
     "Policy used when deciding if audio or video is allowed to autoplay.";
@@ -217,13 +221,6 @@
     "over Bluetooth Low Energy in order to unlock the Chromebook when the "
     "phone is in its proximity.";
 
-const char kEasyUnlockProximityDetectionName[] =
-    "Smart Lock proximity detection";
-const char kEasyUnlockProximityDetectionDescription[] =
-    "Enables a Smart Lock setting that restricts unlocking to only work when "
-    "your phone is very close to (roughly, within an arm's length of) the "
-    "Chrome device.";
-
 const char kEmbeddedExtensionOptionsName[] = "Embedded extension options";
 const char kEmbeddedExtensionOptionsDescription[] =
     "Display extension options as an embedded element in chrome://extensions "
@@ -512,15 +509,260 @@
     "Enables running extensions on chrome:// URLs, where extensions explicitly "
     "request this permission.";
 
-//  Report URL to SafeSearch
+const char kFastUnloadName[] = "Fast tab/window close";
+const char kFastUnloadDescription[] =
+    "Enables fast tab/window closing - runs a tab's onunload js handler "
+    "independently of the GUI.";
 
-const char kSafeSearchUrlReportingName[] = "SafeSearch URLs reporting.";
+const char kFeaturePolicyName[] = "Feature Policy";
+const char kFeaturePolicyDescription[] =
+    "Enables granting and removing access to features through the "
+    "Feature-Policy HTTP header.";
 
-const char kSafeSearchUrlReportingDescription[] =
-    "If enabled, inappropriate URLs can be reported back to SafeSearch.";
+const char kFetchKeepaliveTimeoutSettingName[] =
+    "Fetch API keepalive timeout setting";
+const char kFetchKeepaliveTimeoutSettingDescription[] =
+    "This is for setting the timeout value for Fetch API with keepalive option "
+    "and SendBeacon";
+
+const char kFontCacheScalingName[] = "FontCache scaling";
+const char kFontCacheScalingDescription[] =
+    "Reuse a cached font in the renderer to serve different sizes of font for "
+    "faster layout.";
+
+const char kForceEffectiveConnectionTypeName[] =
+    "Override effective connection type";
+const char kForceEffectiveConnectionTypeDescription[] =
+    "Overrides the effective connection type of the current connection "
+    "returned by the network quality estimator.";
+const char kEffectiveConnectionTypeUnknownDescription[] = "Unknown";
+const char kEffectiveConnectionTypeOfflineDescription[] = "Offline";
+const char kEffectiveConnectionTypeSlow2GDescription[] = "Slow 2G";
+const char kEffectiveConnectionType2GDescription[] = "2G";
+const char kEffectiveConnectionType3GDescription[] = "3G";
+const char kEffectiveConnectionType4GDescription[] = "4G";
+
+const char kFillOnAccountSelectName[] = "Fill passwords on account selection";
+const char kFillOnAccountSelectDescription[] =
+    "Filling of passwords when an account is explicitly selected by the user "
+    "rather than autofilling credentials on page load.";
+
+const char kForceTabletModeName[] = "Force Tablet Mode";
+const char kForceTabletModeDescription[] =
+    R"*(This flag can be used to force a certain mode on to a chromebook, )*"
+    R"*(despite its current orientation. "TouchView" means that the )*"
+    R"*(chromebook will act as if it were in touch view mode. "Clamshell" )*"
+    R"*(means that the chromebook will act as if it were in clamshell )*"
+    R"*(mode . "Auto" means that the chromebook will alternate between )*"
+    R"*(the two, based on its orientation.)*";
+const char kForceTabletModeTouchview[] = "TouchView";
+const char kForceTabletModeClamshell[] = "Clamshell";
+const char kForceTabletModeAuto[] = "Auto (default)";
+
+const char kForceTextDirectionName[] = "Force text direction";
+const char kForceTextDirectionDescription[] =
+    "Explicitly force the per-character directionality of UI text to "
+    "left-to-right (LTR) or right-to-left (RTL) mode, overriding the default "
+    "direction of the character language.";
+const char kForceDirectionLtr[] = "Left-to-right";
+const char kForceDirectionRtl[] = "Right-to-left";
+
+const char kForceUiDirectionName[] = "Force UI direction";
+const char kForceUiDirectionDescription[] =
+    "Explicitly force the UI to left-to-right (LTR) or right-to-left (RTL) "
+    "mode, overriding the default direction of the UI language.";
+
+const char kFramebustingName[] =
+    "Framebusting requires same-origin or a user gesture";
+const char kFramebustingDescription[] =
+    "Don't permit an iframe to navigate the top level browsing context unless "
+    "they are same-origin or the iframe is processing a user gesture.";
+
+const char kGamepadExtensionsName[] = "Gamepad Extensions";
+const char kGamepadExtensionsDescription[] =
+    "Enabling this option allows web applications to access experimental "
+    "extensions to the Gamepad APIs.";
+
+const char kGlCompositedTextureQuadBordersName[] =
+    "GL composited texture quad borders";
+const char kGlCompositedTextureQuadBordersDescription[] =
+    "Renders a border around GL composited texture quads to help debug and "
+    "study overlay support.";
+
+const char kGpuRasterizationMsaaSampleCountName[] =
+    "GPU rasterization MSAA sample count.";
+const char kGpuRasterizationMsaaSampleCountDescription[] =
+    "Specify the number of MSAA samples for GPU rasterization.";
+const char kGpuRasterizationMsaaSampleCountZero[] = "0";
+const char kGpuRasterizationMsaaSampleCountTwo[] = "2";
+const char kGpuRasterizationMsaaSampleCountFour[] = "4";
+const char kGpuRasterizationMsaaSampleCountEight[] = "8";
+const char kGpuRasterizationMsaaSampleCountSixteen[] = "16";
+
+const char kGpuRasterizationName[] = "GPU rasterization";
+const char kGpuRasterizationDescription[] =
+    "Use GPU to rasterize web content. Requires impl-side painting.";
+
+const char kGoogleProfileInfoName[] = "Google profile name and icon";
+const char kGoogleProfileInfoDescription[] =
+    "Enables using Google information to populate the profile name and icon in "
+    "the avatar menu.";
+
+const char kHarfbuzzRendertextName[] = "HarfBuzz for UI text";
+const char kHarfbuzzRendertextDescription[] =
+    "Enable cross-platform HarfBuzz layout engine for UI text. Doesn't affect "
+    "web content.";
+
+const char kHistoryRequiresUserGestureName[] =
+    "New history entries require a user gesture.";
+const char kHistoryRequiresUserGestureDescription[] =
+    "Require a user gesture to add a history entry.";
+const char kHyperlinkAuditingName[] = "Hyperlink auditing";
+const char kHyperlinkAuditingDescription[] = "Sends hyperlink auditing pings.";
+
+const char kHostedAppQuitNotificationName[] =
+    "Quit notification for hosted apps";
+const char kHostedAppQuitNotificationDescription[] =
+    "Display a notification when quitting Chrome if hosted apps are currently "
+    "running.";
+
+const char kHostedAppShimCreationName[] =
+    "Creation of app shims for hosted apps on Mac";
+const char kHostedAppShimCreationDescription[] =
+    "Create app shims on Mac when creating a hosted app.";
+
+const char kIconNtpName[] = "Large icons on the New Tab page";
+const char kIconNtpDescription[] =
+    "Enable the experimental New Tab page using large icons.";
+
+const char kIgnoreGpuBlacklistName[] = "Override software rendering list";
+const char kIgnoreGpuBlacklistDescription[] =
+    "Overrides the built-in software rendering list and enables "
+    "GPU-acceleration on unsupported system configurations.";
+
+const char kImportantSitesInCbdName[] =
+    "Important sites options in clear browsing data dialog";
+const char kImportantSitesInCbdDescription[] =
+    "Include the option to whitelist important sites in the clear browsing "
+    "data dialog.";
+
+const char kInertVisualViewportName[] = "Inert visual viewport.";
+const char kInertVisualViewportDescription[] =
+    "Experiment to have all APIs reflect the layout viewport. This will make "
+    "window.scroll properties relative to the layout viewport.";
+
+const char kInProductHelpDemoModeChoiceName[] = "In-Product Help Demo Mode";
+const char kInProductHelpDemoModeChoiceDescription[] =
+    "Selects the In-Product Help demo mode.";
+
+const char kJavascriptHarmonyName[] = "Experimental JavaScript";
+const char kJavascriptHarmonyDescription[] =
+    "Enable web pages to use experimental JavaScript features.";
+
+const char kJavascriptHarmonyShippingName[] =
+    "Latest stable JavaScript features";
+const char kJavascriptHarmonyShippingDescription[] =
+    "Some web pages use legacy or non-standard JavaScript extensions that may "
+    "conflict with the latest JavaScript features. This flag allows disabling "
+    "support of those features for compatibility with such pages.";
+
+const char kLcdTextName[] = "LCD text antialiasing";
+const char kLcdTextDescription[] =
+    "If disabled, text is rendered with grayscale antialiasing instead of LCD "
+    "(subpixel) when doing accelerated compositing.";
+
+const char kLoadMediaRouterComponentExtensionName[] =
+    "Load Media Router Component Extension";
+const char kLoadMediaRouterComponentExtensionDescription[] =
+    "Loads the Media Router component extension at startup.";
+
+const char kManualPasswordGenerationName[] = "Manual password generation.";
+const char kManualPasswordGenerationDescription[] =
+    "Show a 'Generate Password' option on the context menu for all password "
+    "fields.";
+
+const char kMarkHttpAsName[] = "Mark non-secure origins as non-secure";
+const char kMarkHttpAsDescription[] = "Change the UI treatment for HTTP pages";
+const char kMarkHttpAsDangerous[] = "Always mark HTTP as actively dangerous";
+const char kMarkHttpAsNonSecureAfterEditing[] =
+    "Warn on HTTP after editing forms";
+const char kMarkHttpAsNonSecureWhileIncognito[] =
+    "Warn on HTTP while in Incognito mode";
+const char kMarkHttpAsNonSecureWhileIncognitoOrEditing[] =
+    "Warn on HTTP while in Incognito mode or after editing forms";
+
+extern const char kMaterialDesignIncognitoNTPName[] =
+    "Material Design Incognito NTP.";
+extern const char kMaterialDesignIncognitoNTPDescription[] =
+    "If enabled, the Incognito New Tab page uses the new material design with "
+    "a better readable text.";
+
+const char kMediaRemotingName[] = "Media Remoting during Cast Tab Mirroring";
+const char kMediaRemotingDescription[] =
+    "When Casting a tab to a remote device, enabling this turns on an "
+    "optimization that forwards the content bitstream directly to the remote "
+    "device when a video is fullscreened.";
+
+const char kMemoryAblationName[] = "Memory ablation experiment";
+const char kMemoryAblationDescription[] =
+    "Allocates extra memory in the browser process.";
+
+const char kMemoryCoordinatorName[] = "Memory coordinator";
+const char kMemoryCoordinatorDescription[] =
+    "Enable memory coordinator instead of memory pressure listeners.";
+
+const char kMessageCenterNewStyleNotificationName[] = "New style notification";
+const char kMessageCenterNewStyleNotificationDescription[] =
+    "Enables the experiment style of material-design notification";
+
+const char kMessageCenterAlwaysScrollUpUponRemovalName[] =
+    "Experiments that message center always scroll up upon notification "
+    "removal";
+const char kMessageCenterAlwaysScrollUpUponRemovalDescription[] =
+    "Enables experiment that message center always scroll up when a "
+    "notification is removed.";
+
+const char kMhtmlGeneratorOptionName[] = "MHTML Generation Option";
+const char kMhtmlGeneratorOptionDescription[] =
+    "Provides experimental options for MHTML file generator.";
+const char kMhtmlSkipNostoreMain[] = "Skips no-store main frame.";
+const char kMhtmlSkipNostoreAll[] = "Skips all no-store resources.";
+
+const char kMojoLoadingName[] = "Use Mojo IPC for resource loading";
+const char kMojoLoadingDescription[] =
+    "Use Mojo IPC instead of traditional Chrome IPC for resource loading.";
+
+const char kModuleScriptsName[] = "Enable ECMAScript 6 modules";
+const char kModuleScriptsDescription[] =
+    "Enables ECMAScript 6 modules support in Blink.";
+
+const char kNewAudioRenderingMixingStrategyName[] =
+    "New audio rendering mixing strategy";
+const char kNewAudioRenderingMixingStrategyDescription[] =
+    "Use the new audio rendering mixing strategy.";
+
+const char kNewBookmarkAppsName[] = "The new bookmark app system";
+const char kNewBookmarkAppsDescription[] =
+    "Enables the new system for creating bookmark apps.";
+
+const char kNewOmniboxAnswerTypesName[] =
+    "New omnibox answers in suggest types";
+const char kNewOmniboxAnswerTypesDescription[] =
+    "Enables new types of answers in the omnibox suggest drop-down: currency "
+    "conversions, dictionary definitions, sports scores, translations, and "
+    "when is.";
+
+const char kNewRemotePlaybackPipelineName[] =
+    "Enable the new remote playback pipeline.";
+const char kNewRemotePlaybackPipelineDescription[] =
+    "Enable the new pipeline for playing media element remotely via "
+    "RemotePlayback API or native controls.";
+
+const char kNewUsbBackendName[] = "Enable new USB backend";
+const char kNewUsbBackendDescription[] =
+    "Enables the new experimental USB backend for Windows.";
 
 const char kNostatePrefetchName[] = "No-State Prefetch";
-
 const char kNostatePrefetchDescription[] =
     R"*("No-State Prefetch" pre-downloads resources to improve load )*"
     R"*(times. "Prerender" does a full pre-rendering of the page, to )*"
@@ -528,8 +770,341 @@
     R"*(similar to disabling the feature, but collects more metrics for )*"
     R"*(comparison purposes.)*";
 
-const char kSpeculativePrefetchName[] = "Speculative Prefetch";
+const char kNotificationsNativeFlagName[] = "Enable native notifications.";
+const char kNotificationsNativeFlagDescription[] =
+    "Enable support for using the native notification toasts and notification "
+    "center on platforms where these are available.";
 
+const char kNumRasterThreadsName[] = "Number of raster threads";
+const char kNumRasterThreadsDescription[] =
+    "Specify the number of raster threads.";
+const char kNumRasterThreadsOne[] = "1";
+const char kNumRasterThreadsTwo[] = "2";
+const char kNumRasterThreadsThree[] = "3";
+const char kNumRasterThreadsFour[] = "4";
+
+const char kOfferStoreUnmaskedWalletCardsName[] =
+    "Google Payments card saving checkbox";
+const char kOfferStoreUnmaskedWalletCardsDescription[] =
+    "Show the checkbox to offer local saving of a credit card downloaded from "
+    "the server.";
+
+const char kOfflineAutoReloadName[] = "Offline Auto-Reload Mode";
+const char kOfflineAutoReloadDescription[] =
+    "Pages that fail to load while the browser is offline will be "
+    "auto-reloaded when the browser is online again.";
+
+const char kOfflineAutoReloadVisibleOnlyName[] =
+    "Only Auto-Reload Visible Tabs";
+const char kOfflineAutoReloadVisibleOnlyDescription[] =
+    "Pages that fail to load while the browser is offline will only be "
+    "auto-reloaded if their tab is visible.";
+
+const char kOffMainThreadFetchName[] = "Off-main-thread fetch for Web Workers";
+const char kOffMainThreadFetchDescription[] =
+    "If enabled, the resource fetches from worker threads will not be blocked "
+    "by the busy main thread.";
+
+const char kOmniboxDisplayTitleForCurrentUrlName[] =
+    "Include title for the current URL in the omnibox";
+const char kOmniboxDisplayTitleForCurrentUrlDescription[] =
+    "In the event that the omnibox provides suggestions on-focus, the URL of "
+    "the current page is provided as the first suggestion without a title. "
+    "Enabling this flag causes the title to be displayed.";
+
+const char kOmniboxUIElideSuggestionUrlAfterHostName[] =
+    "Omnibox UI Elide Suggestion URL After Host";
+const char kOmniboxUIElideSuggestionUrlAfterHostDescription[] =
+    "Elides the path, query, and ref of suggested URLs in the Omnibox "
+    "dropdown.";
+
+const char kOmniboxUIHideSuggestionUrlSchemeName[] =
+    "Omnibox UI Hide Suggestion URL Scheme";
+const char kOmniboxUIHideSuggestionUrlSchemeDescription[] =
+    "Elides the schemes of suggested URLs in the Omnibox dropdown.";
+
+const char kOmniboxUIHideSuggestionUrlTrivialSubdomainsName[] =
+    "Omnibox UI Hide Suggestion URL Trivial Subdomains";
+const char kOmniboxUIHideSuggestionUrlTrivialSubdomainsDescription[] =
+    "Elides trivially informative subdomains from suggested URLs in the "
+    "Omnibox dropdown (e.g. www. and m.).";
+
+const char kOmniboxUIMaxAutocompleteMatchesName[] =
+    "Omnibox UI Max Autocomplete Matches";
+
+const char kOmniboxUIMaxAutocompleteMatchesDescription[] =
+    "Changes the maximum number of autocomplete matches displayed in the "
+    "Omnibox UI.";
+
+const char kOmniboxUINarrowDropdownName[] = "Omnibox UI Narrow Dropdown";
+const char kOmniboxUINarrowDropdownDescription[] =
+    "Makes the suggestions dropdown width match the omnibox width.";
+
+const char kOmniboxUIVerticalLayoutName[] = "Omnibox UI Vertical Layout";
+const char kOmniboxUIVerticalLayoutDescription[] =
+    "Displays Omnibox sugestions in 2 lines - title over origin.";
+
+const char kOmniboxUIVerticalMarginName[] = "Omnibox UI Vertical Margin";
+const char kOmniboxUIVerticalMarginDescription[] =
+    "Changes the vertical margin in the Omnibox UI.";
+
+const char kOriginTrialsName[] = "Origin Trials";
+const char kOriginTrialsDescription[] =
+    "Enables origin trials for controlling access to feature/API experiments.";
+
+const char kOverlayScrollbarsName[] = "Overlay Scrollbars";
+const char kOverlayScrollbarsDescription[] =
+    "Enable the experimental overlay scrollbars implementation. You must also "
+    "enable threaded compositing to have the scrollbars animate.";
+
+const char kOverscrollHistoryNavigationName[] = "Overscroll history navigation";
+const char kOverscrollHistoryNavigationDescription[] =
+    "Experimental history navigation in response to horizontal overscroll.";
+const char kOverscrollHistoryNavigationSimpleUi[] = "Simple";
+
+const char kOverscrollStartThresholdName[] = "Overscroll start threshold";
+const char kOverscrollStartThresholdDescription[] =
+    "Changes overscroll start threshold relative to the default value.";
+const char kOverscrollStartThreshold133Percent[] = "133%";
+const char kOverscrollStartThreshold166Percent[] = "166%";
+const char kOverscrollStartThreshold200Percent[] = "200%";
+
+const char kPassiveEventListenerDefaultName[] =
+    "Passive Event Listener Override";
+const char kPassiveEventListenerDefaultDescription[] =
+    "Forces touchstart, touchmove, mousewheel and wheel event listeners (which "
+    "haven't requested otherwise) to be treated as passive. This will break "
+    "touch/wheel behavior on some websites but is useful for demonstrating the "
+    "potential performance benefits of adopting passive event listeners.";
+const char kPassiveEventListenerTrue[] = "True (when unspecified)";
+const char kPassiveEventListenerForceAllTrue[] = "Force All True";
+
+const char kPassiveEventListenersDueToFlingName[] =
+    "Touch Event Listeners Passive Default During Fling";
+const char kPassiveEventListenersDueToFlingDescription[] =
+    "Forces touchstart, and first touchmove per scroll event listeners during "
+    "fling to be treated as passive.";
+
+const char kPassiveDocumentEventListenersName[] =
+    "Document Level Event Listeners Passive Default";
+const char kPassiveDocumentEventListenersDescription[] =
+    "Forces touchstart, and touchmove event listeners on document level "
+    "targets (which haven't requested otherwise) to be treated as passive.";
+
+const char kPasswordForceSavingName[] = "Force-saving of passwords";
+const char kPasswordForceSavingDescription[] =
+    "Allow the user to manually enforce password saving instead of relying on "
+    "password manager's heuristics.";
+
+const char kPasswordGenerationName[] = "Password generation";
+const char kPasswordGenerationDescription[] =
+    "Allow the user to have Chrome generate passwords when it detects account "
+    "creation pages.";
+
+const char kPasswordImportExportName[] = "Password import and export";
+const char kPasswordImportExportDescription[] =
+    "Import and Export functionality in password settings.";
+
+const char kPermissionActionReportingName[] = "Permission Action Reporting";
+const char kPermissionActionReportingDescription[] =
+    "Enables permission action reporting to Safe Browsing servers for opted in "
+    "users.";
+
+const char kPermissionsBlacklistName[] = "Permissions Blacklist";
+const char kPermissionsBlacklistDescription[] =
+    "Enables the Permissions Blacklist, which blocks permissions for "
+    "blacklisted sites for Safe Browsing users.";
+
+const char kPinchScaleName[] = "Pinch scale";
+const char kPinchScaleDescription[] =
+    "Enables experimental support for scale using pinch.";
+
+const char kPreferHtmlOverPluginsName[] = "Prefer HTML over Flash";
+const char kPreferHtmlOverPluginsDescription[] =
+    "Prefer HTML content by hiding Flash from the list of plugins.";
+
+const char kPrintPdfAsImageName[] = "Print Pdf as Image";
+const char kPrintPdfAsImageDescription[] =
+    "If enabled, an option to print PDF files as images will be available in "
+    "print preview.";
+
+const char kPrintPreviewRegisterPromosName[] =
+    "Print Preview Registration Promos";
+const char kPrintPreviewRegisterPromosDescription[] =
+    "Enable registering unregistered cloud printers from print preview.";
+
+const char kProtectSyncCredentialName[] = "Autofill sync credential";
+const char kProtectSyncCredentialDescription[] =
+    "How the password manager handles autofill for the sync credential.";
+
+const char kProtectSyncCredentialOnReauthName[] =
+    "Autofill sync credential only for transactional reauth pages";
+const char kProtectSyncCredentialOnReauthDescription[] =
+    "How the password manager handles autofill for the sync credential only "
+    "for transactional reauth pages.";
+
+const char kPushApiBackgroundModeName[] = "Enable Push API background mode";
+const char kPushApiBackgroundModeDescription[] =
+    "Enable background mode for the Push API. This allows Chrome to continue "
+    "running after the last window is closed, and to launch at OS startup, if "
+    "the Push API needs it.";
+
+const char kQuicName[] = "Experimental QUIC protocol";
+const char kQuicDescription[] = "Enable experimental QUIC protocol support.";
+
+const char kReducedReferrerGranularityName[] =
+    "Reduce default 'referer' header granularity.";
+const char kReducedReferrerGranularityDescription[] =
+    "If a page hasn't set an explicit referrer policy, setting this flag will "
+    "reduce the amount of information in the 'referer' header for cross-origin "
+    "requests.";
+
+const char kRequestTabletSiteName[] =
+    "Request tablet site option in the settings menu";
+const char kRequestTabletSiteDescription[] =
+    "Allows the user to request tablet site. Web content is often optimized "
+    "for tablet devices. When this option is selected the user agent string is "
+    "changed to indicate a tablet device. Web content optimized for tablets is "
+    "received there after for the current tab.";
+
+const char kResetAppListInstallStateName[] =
+    "Reset the App Launcher install state on every restart.";
+const char kResetAppListInstallStateDescription[] =
+    "Reset the App Launcher install state on every restart. While this flag is "
+    "set, Chrome will forget the launcher has been installed each time it "
+    "starts. This is used for testing the App Launcher install flow.";
+
+const char kResourceLoadSchedulerName[] = "Use the resource load scheduler";
+const char kResourceLoadSchedulerDescription[] =
+    "Uses the resource load scheduler in blink to schedule and throttle "
+    "resource load requests.";
+
+const char kRunAllFlashInAllowModeName[] =
+    R"*(Run all Flash content when Flash setting is set to "allow")*";
+const char kRunAllFlashInAllowModeDescription[] =
+    R"*(For sites that have been set to "allow" Flash content, run all )*"
+    R"*(content including any that has been deemed unimportant.)*";
+
+const char kSafeSearchUrlReportingName[] = "SafeSearch URLs reporting.";
+const char kSafeSearchUrlReportingDescription[] =
+    "If enabled, inappropriate URLs can be reported back to SafeSearch.";
+
+const char kSaveasMenuLabelExperimentName[] =
+    "Switch 'Save as' menu labels to 'Download'";
+const char kSaveasMenuLabelExperimentDescription[] =
+    "Enables an experiment to switch menu labels that use 'Save as...' to "
+    "'Download'.";
+
+const char kSavePageAsMhtmlName[] = "Save Page as MHTML";
+const char kSavePageAsMhtmlDescription[] =
+    "Enables saving pages as MHTML: a single text file containing HTML and all "
+    "sub-resources.";
+
+const char kScrollEndEffectName[] = "Scroll end effect";
+const char kScrollEndEffectDescription[] =
+    "Experimental scroll end effect in response to vertical overscroll.";
+
+const char kScrollPredictionName[] = "Scroll prediction";
+const char kScrollPredictionDescription[] =
+    "Predicts the finger's future position during scrolls allowing time to "
+    "render the frame before the finger is there.";
+
+const char kSecondaryUiMd[] =
+    "Material Design in the rest of the browser's native UI";
+const char kSecondaryUiMdDescription[] =
+    "Extends the --top-chrome-md setting to secondary UI (bubbles, dialogs, "
+    "etc.). On Mac, this enables MacViews, which uses toolkit-views for native "
+    "browser dialogs.";
+
+const char kServiceWorkerNavigationPreloadName[] =
+    "Service worker navigation preload.";
+const char kServiceWorkerNavigationPreloadDescription[] =
+    "Enable web pages to use the experimental service worker navigation "
+    "preload API.";
+
+const char kSettingsWindowName[] = "Show settings in a window";
+const char kSettingsWindowDescription[] =
+    "Settings will be shown in a dedicated window instead of as a browser tab.";
+
+const char kShowAutofillSignaturesName[] = "Show autofill signatures.";
+const char kShowAutofillSignaturesDescription[] =
+    "Annotates web forms with Autofill signatures as HTML attributes.";
+
+const char kShowAutofillTypePredictionsName[] = "Show Autofill predictions";
+const char kShowAutofillTypePredictionsDescription[] =
+    "Annotates web forms with Autofill field type predictions as placeholder "
+    "text.";
+
+const char kShowOverdrawFeedbackName[] = "Show overdraw feedback";
+const char kShowOverdrawFeedbackDescription[] =
+    "Visualize overdraw by color-coding elements based on if they have other "
+    "elements drawn underneath.";
+
+const char kShowSavedCopyName[] = "Show Saved Copy Button";
+const char kShowSavedCopyDescription[] =
+    "When a page fails to load, if a stale copy of the page exists in the "
+    "browser cache, a button will be presented to allow the user to load that "
+    "stale copy. The primary enabling choice puts the button in the most "
+    "salient position on the error page; the secondary enabling choice puts it "
+    "secondary to the reload button.";
+const char kEnableShowSavedCopyPrimary[] = "Enable: Primary";
+const char kEnableShowSavedCopySecondary[] = "Enable: Secondary";
+const char kDisableShowSavedCopy[] = "Disable";
+
+const char kShowTouchHudName[] = "Show HUD for touch points";
+const char kShowTouchHudDescription[] =
+    "Enables a heads-up display at the top-left corner of the screen that "
+    "lists information about the touch-points on the screen.";
+
+const char kSilentDebuggerExtensionApiName[] = "Silent Debugging";
+const char kSilentDebuggerExtensionApiDescription[] =
+    "Do not show the infobar when an extension attaches to a page via "
+    "chrome.debugger API. This is required to debug extension background "
+    "pages.";
+
+const char kSimpleCacheBackendName[] = "Simple Cache for HTTP";
+const char kSimpleCacheBackendDescription[] =
+    "The Simple Cache for HTTP is a new cache. It relies on the filesystem for "
+    "disk space allocation.";
+
+const char kSimplifiedFullscreenUiName[] =
+    "Simplified full screen / mouse lock UI.";
+const char kSimplifiedFullscreenUiDescription[] =
+    "A simplified new user experience when entering page-triggered full screen "
+    "or mouse pointer lock states.";
+
+const char kSingleClickAutofillName[] = "Single-click autofill";
+const char kSingleClickAutofillDescription[] =
+    "Make autofill suggestions on initial mouse click on a form element.";
+
+const char kSiteDetails[] = "Site Details";
+const char kSiteDetailsDescription[] =
+    "Adds UI in MD Settings to view all content settings for a specific "
+    "origin.";
+
+const char kSitePerProcessName[] = "Strict site isolation";
+const char kSitePerProcessDescription[] =
+    "Highly experimental security mode that ensures each renderer process "
+    "contains pages from at most one site. In this mode, out-of-process "
+    "iframes will be used whenever an iframe is cross-site.";
+
+const char kSiteSettings[] = "Site settings with All sites and Site details";
+const char kSiteSettingsDescription[] =
+    "Adds new ways of viewing Site settings.";
+
+const char kSlimmingPaintInvalidationName[] = "Slimming paint invalidation.";
+const char kSlimmingPaintInvalidationDescription[] =
+    "Whether to enable a new paint invalidation system.";
+
+const char kSmoothScrollingName[] = "Smooth Scrolling";
+const char kSmoothScrollingDescription[] =
+    "Animate smoothly when scrolling page content.";
+
+const char kSoftwareRasterizerName[] = "3D software rasterizer";
+const char kSoftwareRasterizerDescription[] =
+    "Fall back to a 3D software rasterizer when the GPU cannot be used.";
+
+const char kSpeculativePrefetchName[] = "Speculative Prefetch";
 const char kSpeculativePrefetchDescription[] =
     R"*("Speculative Prefetch" fetches likely resources early to improve )*"
     R"*(load times, based on a local database (see chrome://predictors). )*"
@@ -538,44 +1113,235 @@
 
 const char kSpeculativeServiceWorkerStartOnQueryInputName[] =
     "Enable speculative start of a service worker when a search is predicted.";
-
 const char kSpeculativeServiceWorkerStartOnQueryInputDescription[] =
     "If enabled, when the user enters text in the omnibox that looks like a "
     "a query, any service worker associated with the search engine the query "
     "will be sent to is started early.";
 
-const char kOffMainThreadFetchName[] = "Off-main-thread fetch for Web Workers";
+const char kSpellingFeedbackFieldTrialName[] = "Spelling Feedback Field Trial";
+const char kSpellingFeedbackFieldTrialDescription[] =
+    "Enable the field trial for sending user feedback to spelling service.";
 
-const char kOffMainThreadFetchDescription[] =
-    "If enabled, the resource fetches from worker threads will not be blocked "
-    "by the busy main thread.";
+const char kSslVersionMaxName[] = "Maximum TLS version enabled.";
+const char kSslVersionMaxDescription[] = "Set maximum enabled TLS version.";
+const char kSslVersionMaxTls12[] = "TLS 1.2";
+const char kSslVersionMaxTls13[] = "TLS 1.3";
 
-//  Force Tablet Mode
+const char kSuggestionsWithSubStringMatchName[] =
+    "Substring matching for Autofill suggestions";
+const char kSuggestionsWithSubStringMatchDescription[] =
+    "Match Autofill suggestions based on substrings (token prefixes) rather "
+    "than just prefixes.";
 
-const char kForceTabletModeName[] = "Force Tablet Mode";
+const char kSupervisedUserManagedBookmarksFolderName[] =
+    "Managed bookmarks for supervised users";
+const char kSupervisedUserManagedBookmarksFolderDescription[] =
+    "Enable the managed bookmarks folder for supervised users.";
 
-const char kForceTabletModeDescription[] =
-    R"*(This flag can be used to force a certain mode on to a chromebook, )*"
-    R"*(despite its current orientation. "TouchView" means that the )*"
-    R"*(chromebook will act as if it were in touch view mode. "Clamshell" )*"
-    R"*(means that the chromebook will act as if it were in clamshell )*"
-    R"*(mode . "Auto" means that the chromebook will alternate between )*"
-    R"*(the two, based on its orientation.)*";
+const char kSyncAppListName[] = "App Launcher sync";
+const char kSyncAppListDescription[] =
+    "Enable App Launcher sync. This also enables Folders where available (non "
+    "OSX).";
 
-const char kForceTabletModeTouchview[] = "TouchView";
+const char kSyncSandboxName[] = "Use Chrome Sync sandbox";
+const char kSyncSandboxDescription[] =
+    "Connects to the testing server for Chrome Sync.";
 
-const char kForceTabletModeClamshell[] = "Clamshell";
+const char kTabAudioMutingName[] = "Tab audio muting UI control";
+const char kTabAudioMutingDescription[] =
+    "When enabled, the audio indicators in the tab strip double as tab audio "
+    "mute controls. This also adds commands in the tab context menu for "
+    "quickly muting multiple selected tabs.";
 
-const char kForceTabletModeAuto[] = "Auto (default)";
+const char kTcpFastOpenName[] = "TCP Fast Open";
+const char kTcpFastOpenDescription[] =
+    "Enable the option to send extra authentication information in the initial "
+    "SYN packet for a previously connected client, allowing faster data send "
+    "start.";
 
-//  Print Preview features
-#if !defined(OS_WIN) && !defined(OS_MACOSX)
-const char kPrintPdfAsImageName[] = "Print Pdf as Image";
+const char kTopChromeMd[] = "UI Layout for the browser's top chrome";
+const char kTopChromeMdDescription[] =
+    R"*(Toggles between normal and touch (formerly "hybrid") layouts.)*";
+const char kTopChromeMdMaterial[] = "Normal";
+const char kTopChromeMdMaterialHybrid[] = "Touch";
 
-const char kPrintPdfAsImageDescription[] =
-    "If enabled, an option to print PDF files as images will be available in "
-    "print preview.";
-#endif
+const char kThreadedScrollingName[] = "Threaded scrolling";
+const char kThreadedScrollingDescription[] =
+    "Threaded handling of scroll-related input events. Disabling this will "
+    "force all such scroll events to be handled on the main thread. Note that "
+    "this can dramatically hurt scrolling performance of most websites and is "
+    "intended for testing purposes only.";
+
+const char kTopDocumentIsolationName[] = "Top document isolation";
+const char kTopDocumentIsolationDescription[] =
+    "Highly experimental performance mode where cross-site iframes are kept in "
+    "a separate process from the top document. In this mode, iframes from "
+    "different third-party sites will be allowed to share a process.";
+
+const char kTouchAdjustmentName[] = "Touch adjustment";
+const char kTouchAdjustmentDescription[] =
+    "Refine the position of a touch gesture in order to compensate for touches "
+    "having poor resolution compared to a mouse.";
+
+const char kTouchDragDropName[] = "Touch initiated drag and drop";
+const char kTouchDragDropDescription[] =
+    "Touch drag and drop can be initiated through long press on a draggable "
+    "element.";
+
+const char kTouchEventsName[] = "Touch Events API";
+const char kTouchEventsDescription[] =
+    "Force Touch Events API feature detection to always be enabled or "
+    "disabled, or to be enabled when a touchscreen is detected on startup "
+    "(Automatic, the default).";
+
+const char kTouchSelectionStrategyName[] = "Touch text selection strategy";
+const char kTouchSelectionStrategyDescription[] =
+    "Controls how text selection granularity changes when touch text selection "
+    "handles are dragged. Non-default behavior is experimental.";
+const char kTouchSelectionStrategyCharacter[] = "Character";
+const char kTouchSelectionStrategyDirection[] = "Direction";
+
+const char kTraceUploadUrlName[] = "Trace label for navigation tracing";
+const char kTraceUploadUrlDescription[] =
+    "This is to be used in conjunction with the enable-navigation-tracing "
+    "flag. Please select the label that best describes the recorded traces. "
+    "This will choose the destination the traces are uploaded to. If you are "
+    "not sure, select other. If left empty, no traces will be uploaded.";
+const char kTraceUploadUrlChoiceOther[] = "Other";
+const char kTraceUploadUrlChoiceEmloading[] = "emloading";
+const char kTraceUploadUrlChoiceQa[] = "QA";
+const char kTraceUploadUrlChoiceTesting[] = "Testing";
+
+const char kTranslate2016q2UiName[] = "Translate 2016Q2 UI";
+const char kTranslate2016q2UiDescription[] =
+    "Improved triggering logic and look for Translate Bubble UI";
+
+const char kTranslateLanguageByUlpName[] = "Translate Language by ULP";
+const char kTranslateLanguageByUlpDescription[] =
+    "Improved translate target language and triggering logic by considering "
+    "information from User Language Profile (ULP).";
+
+const char kTrySupportedChannelLayoutsName[] =
+    "Causes audio output streams to check if channel layouts other than the "
+    "default hardware layout are available.";
+const char kTrySupportedChannelLayoutsDescription[] =
+    "Causes audio output streams to check if channel layouts other than the "
+    "default hardware layout are available. Turning this on will allow the OS "
+    "to do stereo to surround expansion if supported. May expose third party "
+    "driver bugs, use with caution.";
+
+const char kUiPartialSwapName[] = "Partial swap";
+const char kUiPartialSwapDescription[] = "Sets partial swap behavior.";
+
+const char kUserConsentForExtensionScriptsName[] =
+    "User consent for extension scripts";
+const char kUserConsentForExtensionScriptsDescription[] =
+    "Require user consent for an extension running a script on the page, if "
+    "the extension requested permission to run on all urls.";
+
+const char kUseSuggestionsEvenIfFewFeatureName[] =
+    "Disable minimum for server-side tile suggestions on NTP.";
+const char kUseSuggestionsEvenIfFewFeatureDescription[] =
+    "Request server-side suggestions even if there are only very few of them "
+    "and use them for tiles on the New Tab Page.";
+
+const char kV8CacheOptionsName[] = "V8 caching mode.";
+const char kV8CacheOptionsDescription[] =
+    "Caching mode for the V8 JavaScript engine.";
+const char kV8CacheOptionsParse[] = "Cache V8 parser data.";
+const char kV8CacheOptionsCode[] = "Cache V8 compiler data.";
+
+const char kV8CacheStrategiesForCacheStorageName[] =
+    "V8 caching strategy for CacheStorage.";
+const char kV8CacheStrategiesForCacheStorageDescription[] =
+    "Caching strategy of scripts in CacheStorage for the V8 JavaScript engine.";
+const char kV8CacheStrategiesForCacheStorageNormal[] = "Normal";
+const char kV8CacheStrategiesForCacheStorageAggressive[] = "Aggressive";
+
+const char kVibrateRequiresUserGestureName[] =
+    "Requiring user gesture for the Vibration API";
+const char kVibrateRequiresUserGestureDescription[] =
+    "Block the Vibration API if no user gesture has been received on the frame "
+    "or any embedded frame.";
+
+const char kVideoFullscreenOrientationLockName[] =
+    "Lock screen orientation when playing a video fullscreen.";
+const char kVideoFullscreenOrientationLockDescription[] =
+    "Lock the screen orientation of the device to match video orientation when "
+    "a video goes fullscreen. Only on phones.";
+
+const char kVideoRotateToFullscreenName[] =
+    "Rotate-to-fullscreen gesture for videos.";
+const char kVideoRotateToFullscreenDescription[] =
+    "Enter/exit fullscreen when device is rotated to/from the orientation of "
+    "the video. Only on phones.";
+
+const char kWalletServiceUseSandboxName[] =
+    "Use Google Payments sandbox servers";
+const char kWalletServiceUseSandboxDescription[] =
+    "For developers: use the sandbox service for Google Payments API calls.";
+
+const char kWebgl2Name[] = "WebGL 2.0";
+const char kWebgl2Description[] = "Allow web applications to access WebGL 2.0.";
+
+const char kWebglDraftExtensionsName[] = "WebGL Draft Extensions";
+const char kWebglDraftExtensionsDescription[] =
+    "Enabling this option allows web applications to access the WebGL "
+    "Extensions that are still in draft status.";
+
+const char kWebMidiName[] = "Web MIDI API";
+const char kWebMidiDescription[] = "Enable Web MIDI API experimental support.";
+
+const char kWebPaymentsName[] = "Web Payments";
+const char kWebPaymentsDescription[] =
+    "Enable Web Payments API integration, a JavaScript API for merchants.";
+
+const char kWebrtcEchoCanceller3Name[] = "WebRTC Echo Canceller 3.";
+const char kWebrtcEchoCanceller3Description[] =
+    "Experimental WebRTC echo canceller (AEC3).";
+
+const char kWebrtcHwDecodingName[] = "WebRTC hardware video decoding";
+const char kWebrtcHwDecodingDescription[] =
+    "Support in WebRTC for decoding video streams using platform hardware.";
+
+const char kWebrtcHwEncodingName[] = "WebRTC hardware video encoding";
+const char kWebrtcHwEncodingDescription[] =
+    "Support in WebRTC for encoding video streams using platform hardware.";
+
+const char kWebrtcHwH264EncodingName[] = "WebRTC hardware h264 video encoding";
+const char kWebrtcHwH264EncodingDescription[] =
+    "Support in WebRTC for encoding h264 video streams using platform "
+    "hardware.";
+
+const char kWebrtcHwVP8EncodingName[] = "WebRTC hardware vp8 video encoding";
+const char kWebrtcHwVP8EncodingDescription[] =
+    "Support in WebRTC for encoding vp8 video streams using platform hardware.";
+
+const char kWebrtcSrtpAesGcmName[] =
+    "Negotiation with GCM cipher suites for SRTP in WebRTC";
+const char kWebrtcSrtpAesGcmDescription[] =
+    "When enabled, WebRTC will try to negotiate GCM cipher suites for SRTP.";
+
+const char kWebrtcStunOriginName[] = "WebRTC Stun origin header";
+const char kWebrtcStunOriginDescription[] =
+    "When enabled, Stun messages generated by WebRTC will contain the Origin "
+    "header.";
+
+const char kWebvrName[] = "WebVR";
+const char kWebvrDescription[] =
+    "Enabling this option allows web applications to access experimental "
+    "Virtual Reality APIs.";
+
+const char kWifiCredentialSyncName[] = "WiFi credential sync";
+const char kWifiCredentialSyncDescription[] =
+    "Enables synchronizing WiFi network settings across devices. When enabled, "
+    "the WiFi credential datatype is registered with Chrome Sync, and WiFi "
+    "credentials are synchronized subject to user preferences. (See also, "
+    "chrome://settings/syncSetup.)";
+
+const char kZeroCopyName[] = "Zero-copy rasterizer";
+const char kZeroCopyDescription[] =
+    "Raster threads write directly to GPU memory associated with tiles.";
 
 #if !defined(DISABLE_NACL)
 
@@ -607,43 +1373,6 @@
 
 #endif
 
-const char kMarkHttpAsName[] = "Mark non-secure origins as non-secure";
-
-const char kMarkHttpAsDescription[] = "Change the UI treatment for HTTP pages";
-const char kMarkHttpAsDangerous[] = "Always mark HTTP as actively dangerous";
-const char kMarkHttpAsNonSecureAfterEditing[] =
-    "Warn on HTTP after editing forms";
-const char kMarkHttpAsNonSecureWhileIncognito[] =
-    "Warn on HTTP while in Incognito mode";
-const char kMarkHttpAsNonSecureWhileIncognitoOrEditing[] =
-    "Warn on HTTP while in Incognito mode or after editing forms";
-
-//  Material design of the Incognito NTP.
-
-extern const char kMaterialDesignIncognitoNTPName[] =
-    "Material Design Incognito NTP.";
-
-extern const char kMaterialDesignIncognitoNTPDescription[] =
-    "If enabled, the Incognito New Tab page uses the new material design with "
-    "a better readable text.";
-
-const char kSavePageAsMhtmlName[] = "Save Page as MHTML";
-
-const char kSavePageAsMhtmlDescription[] =
-    "Enables saving pages as MHTML: a single text file containing HTML and all "
-    "sub-resources.";
-
-//  Flag and values for MHTML Generator options lab.
-
-const char kMhtmlGeneratorOptionName[] = "MHTML Generation Option";
-
-const char kMhtmlGeneratorOptionDescription[] =
-    "Provides experimental options for MHTML file generator.";
-
-const char kMhtmlSkipNostoreMain[] = "Skips no-store main frame.";
-
-const char kMhtmlSkipNostoreAll[] = "Skips all no-store resources.";
-
 #if defined(OS_WIN)
 
 const char kCloudPrintXpsName[] = "XPS in Google Cloud Print";
@@ -655,52 +1384,6 @@
 
 #endif  // defined(OS_WIN)
 
-const char kLoadMediaRouterComponentExtensionName[] =
-    "Load Media Router Component Extension";
-
-const char kLoadMediaRouterComponentExtensionDescription[] =
-    "Loads the Media Router component extension at startup.";
-
-const char kPrintPreviewRegisterPromosName[] =
-    "Print Preview Registration Promos";
-
-const char kPrintPreviewRegisterPromosDescription[] =
-    "Enable registering unregistered cloud printers from print preview.";
-
-const char kScrollPredictionName[] = "Scroll prediction";
-
-const char kTopChromeMd[] = "UI Layout for the browser's top chrome";
-
-const char kTopChromeMdDescription[] =
-    R"*(Toggles between normal and touch (formerly "hybrid") layouts.)*";
-
-const char kTopChromeMdMaterial[] = "Normal";
-
-const char kTopChromeMdMaterialHybrid[] = "Touch";
-
-const char kSiteDetails[] = "Site Details";
-
-const char kSiteDetailsDescription[] =
-    "Adds UI in MD Settings to view all content settings for a specific "
-    "origin.";
-
-const char kSiteSettings[] = "Site settings with All sites and Site details";
-
-const char kSiteSettingsDescription[] =
-    "Adds new ways of viewing Site settings.";
-
-const char kSecondaryUiMd[] =
-    "Material Design in the rest of the browser's native UI";
-
-const char kSecondaryUiMdDescription[] =
-    "Extends the --top-chrome-md setting to secondary UI (bubbles, dialogs, "
-    "etc.). On Mac, this enables MacViews, which uses toolkit-views for native "
-    "browser dialogs.";
-
-const char kScrollPredictionDescription[] =
-    "Predicts the finger's future position during scrolls allowing time to "
-    "render the frame before the finger is there.";
-
 #if defined(OS_ANDROID)
 
 const char kAccessibilityTabSwitcherName[] = "Accessibility Tab Switcher";
@@ -720,36 +1403,6 @@
 
 #endif  // defined(OS_ANDROID)
 
-const char kTouchEventsName[] = "Touch Events API";
-
-const char kTouchEventsDescription[] =
-    "Force Touch Events API feature detection to always be enabled or "
-    "disabled, or to be enabled when a touchscreen is detected on startup "
-    "(Automatic, the default).";
-
-const char kTouchAdjustmentName[] = "Touch adjustment";
-
-const char kTouchAdjustmentDescription[] =
-    "Refine the position of a touch gesture in order to compensate for touches "
-    "having poor resolution compared to a mouse.";
-
-const char kGlCompositedTextureQuadBordersName[] =
-    "GL composited texture quad borders";
-
-const char kGlCompositedTextureQuadBordersDescription[] =
-    "Renders a border around GL composited texture quads to help debug and "
-    "study overlay support.";
-
-const char kShowOverdrawFeedbackName[] = "Show overdraw feedback";
-
-const char kShowOverdrawFeedbackDescription[] =
-    "Visualize overdraw by color-coding elements based on if they have other "
-    "elements drawn underneath.";
-
-const char kUiPartialSwapName[] = "Partial swap";
-
-const char kUiPartialSwapDescription[] = "Sets partial swap behavior.";
-
 const char kDelayReloadStopButtonChangeName[] =
     "Reduce stop/reload button flicker";
 
@@ -757,52 +1410,6 @@
     "Delays display of stop button when page is loading such that short "
     "loads won't show the stop button at all.";
 
-const char kIgnoreGpuBlacklistName[] = "Override software rendering list";
-
-const char kIgnoreGpuBlacklistDescription[] =
-    "Overrides the built-in software rendering list and enables "
-    "GPU-acceleration on unsupported system configurations.";
-
-const char kInertVisualViewportName[] = "Inert visual viewport.";
-
-const char kInertVisualViewportDescription[] =
-    "Experiment to have all APIs reflect the layout viewport. This will make "
-    "window.scroll properties relative to the layout viewport.";
-
-const char kInProductHelpDemoModeChoiceName[] = "In-Product Help Demo Mode";
-
-const char kInProductHelpDemoModeChoiceDescription[] =
-    "Selects the In-Product Help demo mode.";
-
-const char kFastUnloadName[] = "Fast tab/window close";
-
-const char kFastUnloadDescription[] =
-    "Enables fast tab/window closing - runs a tab's onunload js handler "
-    "independently of the GUI.";
-
-const char kFetchKeepaliveTimeoutSettingName[] =
-    "Fetch API keepalive timeout setting";
-const char kFetchKeepaliveTimeoutSettingDescription[] =
-    "This is for setting the timeout value for Fetch API with keepalive option "
-    "and SendBeacon";
-
-const char kUserConsentForExtensionScriptsName[] =
-    "User consent for extension scripts";
-
-const char kUserConsentForExtensionScriptsDescription[] =
-    "Require user consent for an extension running a script on the page, if "
-    "the extension requested permission to run on all urls.";
-
-const char kHistoryRequiresUserGestureName[] =
-    "New history entries require a user gesture.";
-
-const char kHistoryRequiresUserGestureDescription[] =
-    "Require a user gesture to add a history entry.";
-
-const char kHyperlinkAuditingName[] = "Hyperlink auditing";
-
-const char kHyperlinkAuditingDescription[] = "Sends hyperlink auditing pings.";
-
 #if defined(OS_ANDROID)
 
 const char kContextualSearchName[] = "Contextual Search";
@@ -833,123 +1440,6 @@
 
 #endif  // defined(OS_ANDROID)
 
-const char kSmoothScrollingName[] = "Smooth Scrolling";
-
-const char kSmoothScrollingDescription[] =
-    "Animate smoothly when scrolling page content.";
-
-const char kOverlayScrollbarsName[] = "Overlay Scrollbars";
-
-const char kOverlayScrollbarsDescription[] =
-    "Enable the experimental overlay scrollbars implementation. You must also "
-    "enable threaded compositing to have the scrollbars animate.";
-
-const char kShowAutofillTypePredictionsName[] = "Show Autofill predictions";
-
-const char kShowAutofillTypePredictionsDescription[] =
-    "Annotates web forms with Autofill field type predictions as placeholder "
-    "text.";
-
-const char kTcpFastOpenName[] = "TCP Fast Open";
-
-const char kTcpFastOpenDescription[] =
-    "Enable the option to send extra authentication information in the initial "
-    "SYN packet for a previously connected client, allowing faster data send "
-    "start.";
-
-const char kTouchDragDropName[] = "Touch initiated drag and drop";
-
-const char kTouchDragDropDescription[] =
-    "Touch drag and drop can be initiated through long press on a draggable "
-    "element.";
-
-const char kTouchSelectionStrategyName[] = "Touch text selection strategy";
-
-const char kTouchSelectionStrategyDescription[] =
-    "Controls how text selection granularity changes when touch text selection "
-    "handles are dragged. Non-default behavior is experimental.";
-
-const char kTouchSelectionStrategyCharacter[] = "Character";
-
-const char kTouchSelectionStrategyDirection[] = "Direction";
-
-const char kWalletServiceUseSandboxName[] =
-    "Use Google Payments sandbox servers";
-
-const char kWalletServiceUseSandboxDescription[] =
-    "For developers: use the sandbox service for Google Payments API calls.";
-
-const char kOverscrollHistoryNavigationName[] = "Overscroll history navigation";
-
-const char kOverscrollHistoryNavigationDescription[] =
-    "Experimental history navigation in response to horizontal overscroll.";
-
-const char kOverscrollHistoryNavigationSimpleUi[] = "Simple";
-
-const char kOverscrollStartThresholdName[] = "Overscroll start threshold";
-
-const char kOverscrollStartThresholdDescription[] =
-    "Changes overscroll start threshold relative to the default value.";
-
-const char kOverscrollStartThreshold133Percent[] = "133%";
-
-const char kOverscrollStartThreshold166Percent[] = "166%";
-
-const char kOverscrollStartThreshold200Percent[] = "200%";
-
-const char kScrollEndEffectName[] = "Scroll end effect";
-
-const char kScrollEndEffectDescription[] =
-    "Experimental scroll end effect in response to vertical overscroll.";
-
-const char kWebgl2Name[] = "WebGL 2.0";
-
-const char kWebgl2Description[] = "Allow web applications to access WebGL 2.0.";
-
-const char kWebglDraftExtensionsName[] = "WebGL Draft Extensions";
-
-const char kWebglDraftExtensionsDescription[] =
-    "Enabling this option allows web applications to access the WebGL "
-    "Extensions that are still in draft status.";
-
-const char kWebrtcHwDecodingName[] = "WebRTC hardware video decoding";
-
-const char kWebrtcHwDecodingDescription[] =
-    "Support in WebRTC for decoding video streams using platform hardware.";
-
-const char kWebrtcHwEncodingName[] = "WebRTC hardware video encoding";
-
-const char kWebrtcHwEncodingDescription[] =
-    "Support in WebRTC for encoding video streams using platform hardware.";
-
-const char kWebrtcHwH264EncodingName[] = "WebRTC hardware h264 video encoding";
-
-const char kWebrtcHwH264EncodingDescription[] =
-    "Support in WebRTC for encoding h264 video streams using platform "
-    "hardware.";
-
-const char kWebrtcHwVP8EncodingName[] = "WebRTC hardware vp8 video encoding";
-
-const char kWebrtcHwVP8EncodingDescription[] =
-    "Support in WebRTC for encoding vp8 video streams using platform hardware.";
-
-const char kWebrtcSrtpAesGcmName[] =
-    "Negotiation with GCM cipher suites for SRTP in WebRTC";
-
-const char kWebrtcSrtpAesGcmDescription[] =
-    "When enabled, WebRTC will try to negotiate GCM cipher suites for SRTP.";
-
-const char kWebrtcStunOriginName[] = "WebRTC Stun origin header";
-
-const char kWebrtcStunOriginDescription[] =
-    "When enabled, Stun messages generated by WebRTC will contain the Origin "
-    "header.";
-
-const char kWebrtcEchoCanceller3Name[] = "WebRTC Echo Canceller 3.";
-
-const char kWebrtcEchoCanceller3Description[] =
-    "Experimental WebRTC echo canceller (AEC3).";
-
 #if defined(OS_ANDROID)
 
 const char kMediaScreenCaptureName[] = "Experimental ScreenCapture.";
@@ -971,29 +1461,6 @@
 
 #endif  // BUILDFLAG(ENABLE_WEBRTC)
 
-const char kWebvrName[] = "WebVR";
-
-const char kWebvrDescription[] =
-    "Enabling this option allows web applications to access experimental "
-    "Virtual Reality APIs.";
-
-#if BUILDFLAG(ENABLE_VR)
-
-const char kWebvrExperimentalRenderingName[] =
-    "WebVR experimental rendering optimizations";
-
-const char kWebvrExperimentalRenderingDescription[] =
-    "Enabling this option activates experimental rendering path optimizations "
-    "for WebVR.";
-
-#endif  // BUILDFLAG(ENABLE_VR)
-
-const char kGamepadExtensionsName[] = "Gamepad Extensions";
-
-const char kGamepadExtensionsDescription[] =
-    "Enabling this option allows web applications to access experimental "
-    "extensions to the Gamepad APIs.";
-
 #if defined(OS_ANDROID)
 
 const char kNewPhotoPickerName[] = "Enable new Photopicker";
@@ -1013,52 +1480,6 @@
 
 #endif  // defined(OS_ANDROID)
 
-const char kQuicName[] = "Experimental QUIC protocol";
-
-const char kQuicDescription[] = "Enable experimental QUIC protocol support.";
-
-const char kSslVersionMaxName[] = "Maximum TLS version enabled.";
-
-const char kSslVersionMaxDescription[] = "Set maximum enabled TLS version.";
-
-const char kSslVersionMaxTls12[] = "TLS 1.2";
-
-const char kSslVersionMaxTls13[] = "TLS 1.3";
-
-const char kPassiveDocumentEventListenersDescription[] =
-    "Forces touchstart, and touchmove event listeners on document level "
-    "targets (which haven't requested otherwise) to be treated as passive.";
-
-const char kPassiveDocumentEventListenersName[] =
-    "Document Level Event Listeners Passive Default";
-
-const char kPassiveEventListenersDueToFlingDescription[] =
-    "Forces touchstart, and first touchmove per scroll event listeners during "
-    "fling to be treated as passive.";
-
-const char kPassiveEventListenersDueToFlingName[] =
-    "Touch Event Listeners Passive Default During Fling";
-
-const char kPassiveEventListenerTrue[] = "True (when unspecified)";
-
-const char kPassiveEventListenerForceAllTrue[] = "Force All True";
-
-const char kPassiveEventListenerDefaultName[] =
-    "Passive Event Listener Override";
-
-const char kPassiveEventListenerDefaultDescription[] =
-    "Forces touchstart, touchmove, mousewheel and wheel event listeners (which "
-    "haven't requested otherwise) to be treated as passive. This will break "
-    "touch/wheel behavior on some websites but is useful for demonstrating the "
-    "potential performance benefits of adopting passive event listeners.";
-
-const char kImportantSitesInCbdName[] =
-    "Important sites options in clear browsing data dialog";
-
-const char kImportantSitesInCbdDescription[] =
-    "Include the option to whitelist important sites in the clear browsing "
-    "data dialog.";
-
 #if defined(USE_ASH)
 
 const char kAshShelfColorName[] = "Shelf color in Chrome OS system UI";
@@ -1128,19 +1549,6 @@
 
 #endif  // defined(USE_ASH)
 
-const char kJavascriptHarmonyShippingName[] =
-    "Latest stable JavaScript features";
-
-const char kJavascriptHarmonyShippingDescription[] =
-    "Some web pages use legacy or non-standard JavaScript extensions that may "
-    "conflict with the latest JavaScript features. This flag allows disabling "
-    "support of those features for compatibility with such pages.";
-
-const char kJavascriptHarmonyName[] = "Experimental JavaScript";
-
-const char kJavascriptHarmonyDescription[] =
-    "Enable web pages to use experimental JavaScript features.";
-
 #if defined(OS_ANDROID)
 
 const char kMediaDocumentDownloadButtonName[] =
@@ -1151,82 +1559,8 @@
 
 #endif  // defined(OS_ANDROID)
 
-const char kSoftwareRasterizerName[] = "3D software rasterizer";
-
-const char kSoftwareRasterizerDescription[] =
-    "Fall back to a 3D software rasterizer when the GPU cannot be used.";
-
-const char kGpuRasterizationName[] = "GPU rasterization";
-
-const char kGpuRasterizationDescription[] =
-    "Use GPU to rasterize web content. Requires impl-side painting.";
-
 const char kForceGpuRasterization[] = "Force-enabled for all layers";
 
-const char kGpuRasterizationMsaaSampleCountName[] =
-    "GPU rasterization MSAA sample count.";
-
-const char kGpuRasterizationMsaaSampleCountDescription[] =
-    "Specify the number of MSAA samples for GPU rasterization.";
-
-const char kGpuRasterizationMsaaSampleCountZero[] = "0";
-
-const char kGpuRasterizationMsaaSampleCountTwo[] = "2";
-
-const char kGpuRasterizationMsaaSampleCountFour[] = "4";
-
-const char kGpuRasterizationMsaaSampleCountEight[] = "8";
-
-const char kGpuRasterizationMsaaSampleCountSixteen[] = "16";
-
-const char kSlimmingPaintInvalidationName[] = "Slimming paint invalidation.";
-
-const char kSlimmingPaintInvalidationDescription[] =
-    "Whether to enable a new paint invalidation system.";
-
-const char kOriginTrialsName[] = "Origin Trials";
-
-const char kOriginTrialsDescription[] =
-    "Enables origin trials for controlling access to feature/API experiments.";
-
-const char kSilentDebuggerExtensionApiName[] = "Silent Debugging";
-
-const char kSilentDebuggerExtensionApiDescription[] =
-    "Do not show the infobar when an extension attaches to a page via "
-    "chrome.debugger API. This is required to debug extension background "
-    "pages.";
-
-const char kShowTouchHudName[] = "Show HUD for touch points";
-
-const char kShowTouchHudDescription[] =
-    "Enables a heads-up display at the top-left corner of the screen that "
-    "lists information about the touch-points on the screen.";
-
-const char kPreferHtmlOverPluginsName[] = "Prefer HTML over Flash";
-
-const char kPreferHtmlOverPluginsDescription[] =
-    "Prefer HTML content by hiding Flash from the list of plugins.";
-
-const char kRunAllFlashInAllowModeName[] =
-    R"*(Run all Flash content when Flash setting is set to "allow")*";
-
-const char kRunAllFlashInAllowModeDescription[] =
-    R"*(For sites that have been set to "allow" Flash content, run all )*"
-    R"*(content including any that has been deemed unimportant.)*";
-
-const char kPinchScaleName[] = "Pinch scale";
-
-const char kPinchScaleDescription[] =
-    "Enables experimental support for scale using pinch.";
-
-const char kReducedReferrerGranularityName[] =
-    "Reduce default 'referer' header granularity.";
-
-const char kReducedReferrerGranularityDescription[] =
-    "If a page hasn't set an explicit referrer policy, setting this flag will "
-    "reduce the amount of information in the 'referer' header for cross-origin "
-    "requests.";
-
 #if defined(OS_CHROMEOS)
 
 const char kUseMusDescription[] = "Enable the Mojo UI service.";
@@ -1263,133 +1597,6 @@
 
 #endif  // defined(OS_CHROMEOS)
 
-const char kRequestTabletSiteName[] =
-    "Request tablet site option in the settings menu";
-
-const char kRequestTabletSiteDescription[] =
-    "Allows the user to request tablet site. Web content is often optimized "
-    "for tablet devices. When this option is selected the user agent string is "
-    "changed to indicate a tablet device. Web content optimized for tablets is "
-    "received there after for the current tab.";
-
-const char kPasswordGenerationName[] = "Password generation";
-
-const char kPasswordGenerationDescription[] =
-    "Allow the user to have Chrome generate passwords when it detects account "
-    "creation pages.";
-
-const char kPasswordForceSavingName[] = "Force-saving of passwords";
-
-const char kPasswordForceSavingDescription[] =
-    "Allow the user to manually enforce password saving instead of relying on "
-    "password manager's heuristics.";
-
-const char kManualPasswordGenerationName[] = "Manual password generation.";
-
-const char kManualPasswordGenerationDescription[] =
-    "Show a 'Generate Password' option on the context menu for all password "
-    "fields.";
-
-const char kShowAutofillSignaturesName[] = "Show autofill signatures.";
-
-const char kShowAutofillSignaturesDescription[] =
-    "Annotates web forms with Autofill signatures as HTML attributes.";
-
-const char kSuggestionsWithSubStringMatchName[] =
-    "Substring matching for Autofill suggestions";
-
-const char kSuggestionsWithSubStringMatchDescription[] =
-    "Match Autofill suggestions based on substrings (token prefixes) rather "
-    "than just prefixes.";
-
-const char kProtectSyncCredentialName[] = "Autofill sync credential";
-
-const char kProtectSyncCredentialDescription[] =
-    "How the password manager handles autofill for the sync credential.";
-
-const char kPasswordImportExportName[] = "Password import and export";
-
-const char kPasswordImportExportDescription[] =
-    "Import and Export functionality in password settings.";
-
-const char kProtectSyncCredentialOnReauthName[] =
-    "Autofill sync credential only for transactional reauth pages";
-
-const char kProtectSyncCredentialOnReauthDescription[] =
-    "How the password manager handles autofill for the sync credential only "
-    "for transactional reauth pages.";
-
-const char kIconNtpName[] = "Large icons on the New Tab page";
-
-const char kIconNtpDescription[] =
-    "Enable the experimental New Tab page using large icons.";
-
-const char kPushApiBackgroundModeName[] = "Enable Push API background mode";
-
-const char kPushApiBackgroundModeDescription[] =
-    "Enable background mode for the Push API. This allows Chrome to continue "
-    "running after the last window is closed, and to launch at OS startup, if "
-    "the Push API needs it.";
-
-const char kTraceUploadUrlName[] = "Trace label for navigation tracing";
-
-const char kTraceUploadUrlDescription[] =
-    "This is to be used in conjunction with the enable-navigation-tracing "
-    "flag. Please select the label that best describes the recorded traces. "
-    "This will choose the destination the traces are uploaded to. If you are "
-    "not sure, select other. If left empty, no traces will be uploaded.";
-
-const char kTraceUploadUrlChoiceOther[] = "Other";
-
-const char kTraceUploadUrlChoiceEmloading[] = "emloading";
-
-const char kTraceUploadUrlChoiceQa[] = "QA";
-
-const char kTraceUploadUrlChoiceTesting[] = "Testing";
-
-const char kSupervisedUserManagedBookmarksFolderName[] =
-    "Managed bookmarks for supervised users";
-
-const char kSupervisedUserManagedBookmarksFolderDescription[] =
-    "Enable the managed bookmarks folder for supervised users.";
-
-const char kSyncAppListName[] = "App Launcher sync";
-
-const char kSyncAppListDescription[] =
-    "Enable App Launcher sync. This also enables Folders where available (non "
-    "OSX).";
-
-const char kV8CacheOptionsName[] = "V8 caching mode.";
-
-const char kV8CacheOptionsDescription[] =
-    "Caching mode for the V8 JavaScript engine.";
-
-const char kV8CacheOptionsParse[] = "Cache V8 parser data.";
-
-const char kV8CacheOptionsCode[] = "Cache V8 compiler data.";
-
-const char kV8CacheStrategiesForCacheStorageName[] =
-    "V8 caching strategy for CacheStorage.";
-
-const char kV8CacheStrategiesForCacheStorageDescription[] =
-    "Caching strategy of scripts in CacheStorage for the V8 JavaScript engine.";
-
-const char kV8CacheStrategiesForCacheStorageNormal[] = "Normal";
-
-const char kV8CacheStrategiesForCacheStorageAggressive[] = "Aggressive";
-
-const char kMemoryCoordinatorName[] = "Memory coordinator";
-
-const char kMemoryCoordinatorDescription[] =
-    "Enable memory coordinator instead of memory pressure listeners.";
-
-const char kServiceWorkerNavigationPreloadName[] =
-    "Service worker navigation preload.";
-
-const char kServiceWorkerNavigationPreloadDescription[] =
-    "Enable web pages to use the experimental service worker navigation "
-    "preload API.";
-
 #if defined(OS_ANDROID)
 
 const char kEnableDataReductionProxyMainMenuName[] =
@@ -1411,44 +1618,6 @@
 
 #endif  // defined(OS_ANDROID)
 
-const char kLcdTextName[] = "LCD text antialiasing";
-
-const char kLcdTextDescription[] =
-    "If disabled, text is rendered with grayscale antialiasing instead of LCD "
-    "(subpixel) when doing accelerated compositing.";
-
-const char kZeroCopyName[] = "Zero-copy rasterizer";
-
-const char kZeroCopyDescription[] =
-    "Raster threads write directly to GPU memory associated with tiles.";
-
-const char kNumRasterThreadsName[] = "Number of raster threads";
-
-const char kNumRasterThreadsDescription[] =
-    "Specify the number of raster threads.";
-
-const char kNumRasterThreadsOne[] = "1";
-
-const char kNumRasterThreadsTwo[] = "2";
-
-const char kNumRasterThreadsThree[] = "3";
-
-const char kNumRasterThreadsFour[] = "4";
-
-const char kResetAppListInstallStateName[] =
-    "Reset the App Launcher install state on every restart.";
-
-const char kResetAppListInstallStateDescription[] =
-    "Reset the App Launcher install state on every restart. While this flag is "
-    "set, Chrome will forget the launcher has been installed each time it "
-    "starts. This is used for testing the App Launcher install flow.";
-
-const char kResourceLoadSchedulerName[] = "Use the resource load scheduler";
-
-const char kResourceLoadSchedulerDescription[] =
-    "Uses the resource load scheduler in blink to schedule and throttle "
-    "resource load requests.";
-
 #if defined(OS_CHROMEOS)
 
 const char kFirstRunUiTransitionsName[] =
@@ -1459,11 +1628,6 @@
 
 #endif  // defined(OS_CHROMEOS)
 
-const char kNewBookmarkAppsName[] = "The new bookmark app system";
-
-const char kNewBookmarkAppsDescription[] =
-    "Enables the new system for creating bookmark apps.";
-
 #if defined(OS_MACOSX)
 
 const char kHostedAppsInWindowsName[] =
@@ -1493,19 +1657,6 @@
 
 #endif  // defined(OS_MACOSX)
 
-const char kHostedAppShimCreationName[] =
-    "Creation of app shims for hosted apps on Mac";
-
-const char kHostedAppShimCreationDescription[] =
-    "Create app shims on Mac when creating a hosted app.";
-
-const char kHostedAppQuitNotificationName[] =
-    "Quit notification for hosted apps";
-
-const char kHostedAppQuitNotificationDescription[] =
-    "Display a notification when quitting Chrome if hosted apps are currently "
-    "running.";
-
 #if defined(OS_ANDROID)
 
 const char kPullToRefreshEffectName[] = "The pull-to-refresh effect";
@@ -1529,73 +1680,6 @@
 
 #endif  // defined(OS_MACOSX)
 
-const char kTranslate2016q2UiName[] = "Translate 2016Q2 UI";
-
-const char kTranslate2016q2UiDescription[] =
-    "Improved triggering logic and look for Translate Bubble UI";
-
-const char kTranslateLanguageByUlpName[] = "Translate Language by ULP";
-
-const char kTranslateLanguageByUlpDescription[] =
-    "Improved translate target language and triggering logic by considering "
-    "information from User Language Profile (ULP).";
-
-const char kPermissionActionReportingName[] = "Permission Action Reporting";
-
-const char kPermissionActionReportingDescription[] =
-    "Enables permission action reporting to Safe Browsing servers for opted in "
-    "users.";
-
-const char kPermissionsBlacklistName[] = "Permissions Blacklist";
-
-const char kPermissionsBlacklistDescription[] =
-    "Enables the Permissions Blacklist, which blocks permissions for "
-    "blacklisted sites for Safe Browsing users.";
-
-const char kThreadedScrollingName[] = "Threaded scrolling";
-
-const char kThreadedScrollingDescription[] =
-    "Threaded handling of scroll-related input events. Disabling this will "
-    "force all such scroll events to be handled on the main thread. Note that "
-    "this can dramatically hurt scrolling performance of most websites and is "
-    "intended for testing purposes only.";
-
-const char kHarfbuzzRendertextName[] = "HarfBuzz for UI text";
-
-const char kHarfbuzzRendertextDescription[] =
-    "Enable cross-platform HarfBuzz layout engine for UI text. Doesn't affect "
-    "web content.";
-
-const char kTabAudioMutingName[] = "Tab audio muting UI control";
-
-const char kTabAudioMutingDescription[] =
-    "When enabled, the audio indicators in the tab strip double as tab audio "
-    "mute controls. This also adds commands in the tab context menu for "
-    "quickly muting multiple selected tabs.";
-
-const char kWifiCredentialSyncName[] = "WiFi credential sync";
-
-const char kWifiCredentialSyncDescription[] =
-    "Enables synchronizing WiFi network settings across devices. When enabled, "
-    "the WiFi credential datatype is registered with Chrome Sync, and WiFi "
-    "credentials are synchronized subject to user preferences. (See also, "
-    "chrome://settings/syncSetup.)";
-
-const char kSyncSandboxName[] = "Use Chrome Sync sandbox";
-
-const char kSyncSandboxDescription[] =
-    "Connects to the testing server for Chrome Sync.";
-
-const char kTrySupportedChannelLayoutsName[] =
-    "Causes audio output streams to check if channel layouts other than the "
-    "default hardware layout are available.";
-
-const char kTrySupportedChannelLayoutsDescription[] =
-    "Causes audio output streams to check if channel layouts other than the "
-    "default hardware layout are available. Turning this on will allow the OS "
-    "to do stereo to surround expansion if supported. May expose third party "
-    "driver bugs, use with caution.";
-
 #if defined(OS_MACOSX)
 
 const char kAppInfoDialogName[] = "Toolkit-Views App Info Dialog.";
@@ -1643,13 +1727,6 @@
 
 #endif  // defined(OS_CHROMEOS)
 
-const char kSimplifiedFullscreenUiName[] =
-    "Simplified full screen / mouse lock UI.";
-
-const char kSimplifiedFullscreenUiDescription[] =
-    "A simplified new user experience when entering page-triggered full screen "
-    "or mouse pointer lock states.";
-
 #if defined(OS_ANDROID)
 
 extern const char kPayWithGoogleV1Name[] = "Pay with Google v1";
@@ -1726,23 +1803,6 @@
 
 #endif  // defined(TOOLKIT_VIEWS) || defined(OS_ANDROID)
 
-const char kForceUiDirectionName[] = "Force UI direction";
-
-const char kForceUiDirectionDescription[] =
-    "Explicitly force the UI to left-to-right (LTR) or right-to-left (RTL) "
-    "mode, overriding the default direction of the UI language.";
-
-const char kForceTextDirectionName[] = "Force text direction";
-
-const char kForceTextDirectionDescription[] =
-    "Explicitly force the per-character directionality of UI text to "
-    "left-to-right (LTR) or right-to-left (RTL) mode, overriding the default "
-    "direction of the character language.";
-
-const char kForceDirectionLtr[] = "Left-to-right";
-
-const char kForceDirectionRtl[] = "Right-to-left";
-
 #if defined(OS_WIN) || defined(OS_LINUX)
 
 const char kEnableInputImeApiName[] = "Enable Input IME API";
@@ -1752,32 +1812,6 @@
 
 #endif  // defined(OS_WIN) || defined(OS_LINUX)
 
-const char kSaveasMenuLabelExperimentName[] =
-    "Switch 'Save as' menu labels to 'Download'";
-
-const char kSaveasMenuLabelExperimentDescription[] =
-    "Enables an experiment to switch menu labels that use 'Save as...' to "
-    "'Download'.";
-
-const char kNewUsbBackendName[] = "Enable new USB backend";
-
-const char kNewUsbBackendDescription[] =
-    "Enables the new experimental USB backend for Windows.";
-
-const char kNewOmniboxAnswerTypesName[] =
-    "New omnibox answers in suggest types";
-
-const char kNewOmniboxAnswerTypesDescription[] =
-    "Enables new types of answers in the omnibox suggest drop-down: currency "
-    "conversions, dictionary definitions, sports scores, translations, and "
-    "when is.";
-
-const char kFillOnAccountSelectName[] = "Fill passwords on account selection";
-
-const char kFillOnAccountSelectDescription[] =
-    "Filling of passwords when an account is explicitly selected by the user "
-    "rather than autofilling credentials on page load.";
-
 #if defined(OS_ANDROID)
 
 const char kTabsInCbdName[] = "Enable tabs for the Clear Browsing Data dialog.";
@@ -1787,12 +1821,6 @@
 
 #endif  // defined(OS_ANDROID)
 
-const char kNotificationsNativeFlagName[] = "Enable native notifications.";
-
-const char kNotificationsNativeFlagDescription[] =
-    "Enable support for using the native notification toasts and notification "
-    "center on platforms where these are available.";
-
 #if defined(OS_ANDROID)
 
 const char kEnableAndroidSpellcheckerDescription[] =
@@ -1802,47 +1830,6 @@
 
 #endif  // defined(OS_ANDROID)
 
-const char kGoogleProfileInfoName[] = "Google profile name and icon";
-
-const char kGoogleProfileInfoDescription[] =
-    "Enables using Google information to populate the profile name and icon in "
-    "the avatar menu.";
-
-const char kOfferStoreUnmaskedWalletCardsName[] =
-    "Google Payments card saving checkbox";
-
-const char kOfferStoreUnmaskedWalletCardsDescription[] =
-    "Show the checkbox to offer local saving of a credit card downloaded from "
-    "the server.";
-
-const char kOfflineAutoReloadName[] = "Offline Auto-Reload Mode";
-
-const char kOfflineAutoReloadDescription[] =
-    "Pages that fail to load while the browser is offline will be "
-    "auto-reloaded when the browser is online again.";
-
-const char kOfflineAutoReloadVisibleOnlyName[] =
-    "Only Auto-Reload Visible Tabs";
-
-const char kOfflineAutoReloadVisibleOnlyDescription[] =
-    "Pages that fail to load while the browser is offline will only be "
-    "auto-reloaded if their tab is visible.";
-
-const char kShowSavedCopyName[] = "Show Saved Copy Button";
-
-const char kShowSavedCopyDescription[] =
-    "When a page fails to load, if a stale copy of the page exists in the "
-    "browser cache, a button will be presented to allow the user to load that "
-    "stale copy. The primary enabling choice puts the button in the most "
-    "salient position on the error page; the secondary enabling choice puts it "
-    "secondary to the reload button.";
-
-const char kEnableShowSavedCopyPrimary[] = "Enable: Primary";
-
-const char kEnableShowSavedCopySecondary[] = "Enable: Secondary";
-
-const char kDisableShowSavedCopy[] = "Disable";
-
 #if defined(OS_CHROMEOS)
 
 const char kVirtualKeyboardName[] = "Virtual Keyboard";
@@ -1920,47 +1907,6 @@
 
 #endif  // defined(OS_CHROMEOS)
 
-//  Strings for controlling credit card scanning feature in about:flags.
-
-//  Simple Cache Backend experiment.
-
-const char kSimpleCacheBackendName[] = "Simple Cache for HTTP";
-
-const char kSimpleCacheBackendDescription[] =
-    "The Simple Cache for HTTP is a new cache. It relies on the filesystem for "
-    "disk space allocation.";
-
-//  Spelling feedback field trial.
-
-const char kSpellingFeedbackFieldTrialName[] = "Spelling Feedback Field Trial";
-
-const char kSpellingFeedbackFieldTrialDescription[] =
-    "Enable the field trial for sending user feedback to spelling service.";
-
-//  Web MIDI API.
-
-const char kWebMidiName[] = "Web MIDI API";
-
-const char kWebMidiDescription[] = "Enable Web MIDI API experimental support.";
-
-//  Site per process mode
-
-const char kSitePerProcessName[] = "Strict site isolation";
-
-const char kSitePerProcessDescription[] =
-    "Highly experimental security mode that ensures each renderer process "
-    "contains pages from at most one site. In this mode, out-of-process "
-    "iframes will be used whenever an iframe is cross-site.";
-
-//  Top document isolation mode
-
-const char kTopDocumentIsolationName[] = "Top document isolation";
-
-const char kTopDocumentIsolationDescription[] =
-    "Highly experimental performance mode where cross-site iframes are kept in "
-    "a separate process from the top document. In this mode, iframes from "
-    "different third-party sites will be allowed to share a process.";
-
 //  Arc authorization
 
 #if defined(OS_CHROMEOS)
@@ -1973,13 +1919,6 @@
 
 #endif  // defined(OS_CHROMEOS)
 
-//  Autofill experiment flags
-
-const char kSingleClickAutofillName[] = "Single-click autofill";
-
-const char kSingleClickAutofillDescription[] =
-    "Make autofill suggestions on initial mouse click on a form element.";
-
 #if defined(OS_ANDROID)
 
 const char kAutofillAccessoryViewName[] =
@@ -2038,28 +1977,6 @@
 
 #endif  // defined(OS_ANDROID)
 
-//  Settings window flags
-
-const char kSettingsWindowName[] = "Show settings in a window";
-
-const char kSettingsWindowDescription[] =
-    "Settings will be shown in a dedicated window instead of as a browser tab.";
-
-//  Message center strings
-
-const char kMessageCenterAlwaysScrollUpUponRemovalName[] =
-    "Experiments that message center always scroll up upon notification "
-    "removal";
-
-const char kMessageCenterAlwaysScrollUpUponRemovalDescription[] =
-    "Enables experiment that message center always scroll up when a "
-    "notification is removed.";
-
-const char kMessageCenterNewStyleNotificationName[] = "New style notification";
-
-const char kMessageCenterNewStyleNotificationDescription[] =
-    "Enables the experiment style of material-design notification";
-
 #if defined(OS_WIN) || defined(OS_MACOSX)
 
 //  Tab discarding
@@ -2476,52 +2393,31 @@
 
 #endif  // !defined(OS_ANDROID) && defined(GOOGLE_CHROME_BUILD)
 
-const char kFontCacheScalingName[] = "FontCache scaling";
-
-const char kFontCacheScalingDescription[] =
-    "Reuse a cached font in the renderer to serve different sizes of font for "
-    "faster layout.";
-
-const char kFramebustingName[] =
-    "Framebusting requires same-origin or a user gesture";
-
-const char kFramebustingDescription[] =
-    "Don't permit an iframe to navigate the top level browsing context unless "
-    "they are same-origin or the iframe is processing a user gesture.";
-
-const char kVibrateRequiresUserGestureName[] =
-    "Requiring user gesture for the Vibration API";
-
-const char kVibrateRequiresUserGestureDescription[] =
-    "Block the Vibration API if no user gesture has been received on the frame "
-    "or any embedded frame.";
-
-#if defined(OS_ANDROID)
 #if BUILDFLAG(ENABLE_VR)
-const char kEnableVrShellName[] = "Enable Chrome VR.";
+#if defined(OS_ANDROID)
 
+const char kEnableVrShellName[] = "Enable Chrome VR.";
 const char kEnableVrShellDescription[] =
     "Allow browsing with a VR headset if available for this device.";
 
 const char kVrCustomTabBrowsingName[] = "Enable Custom Tab browsing in VR.";
-
 const char kVrCustomTabBrowsingDescription[] =
     "Allow browsing with a VR headset in a Custom Tab if available for this "
     "device.";
 
 const char kWebVrAutopresentName[] = "Enable WebVr auto presentation";
-
 const char kWebVrAutopresentDescription[] =
     "Allows auto presentation of WebVr content from trusted first-party apps";
-#endif  // BUILDFLAG(ENABLE_VR)
+
 #endif  // defined(OS_ANDROID)
 
-//  Web payments
+const char kWebvrExperimentalRenderingName[] =
+    "WebVR experimental rendering optimizations";
+const char kWebvrExperimentalRenderingDescription[] =
+    "Enabling this option activates experimental rendering path optimizations "
+    "for WebVR.";
 
-const char kWebPaymentsName[] = "Web Payments";
-
-const char kWebPaymentsDescription[] =
-    "Enable Web Payments API integration, a JavaScript API for merchants.";
+#endif  // BUILDFLAG(ENABLE_VR)
 
 #if defined(OS_ANDROID)
 
@@ -2554,49 +2450,6 @@
 
 #endif  // defined(OS_ANDROID)
 
-const char kFeaturePolicyName[] = "Feature Policy";
-
-const char kFeaturePolicyDescription[] =
-    "Enables granting and removing access to features through the "
-    "Feature-Policy HTTP header.";
-
-//  Audio rendering mixing experiment strings.
-
-const char kNewAudioRenderingMixingStrategyName[] =
-    "New audio rendering mixing strategy";
-
-const char kNewAudioRenderingMixingStrategyDescription[] =
-    "Use the new audio rendering mixing strategy.";
-
-//  New remote playback pipeline experiment strings.
-
-const char kNewRemotePlaybackPipelineName[] =
-    "Enable the new remote playback pipeline.";
-
-const char kNewRemotePlaybackPipelineDescription[] =
-    "Enable the new pipeline for playing media element remotely via "
-    "RemotePlayback API or native controls.";
-
-//  Video fullscreen with orientation lock experiment strings.
-
-const char kVideoFullscreenOrientationLockName[] =
-    "Lock screen orientation when playing a video fullscreen.";
-
-const char kVideoFullscreenOrientationLockDescription[] =
-    "Lock the screen orientation of the device to match video orientation when "
-    "a video goes fullscreen. Only on phones.";
-
-//  Video rotate-to-fullscreen experiment strings.
-
-const char kVideoRotateToFullscreenName[] =
-    "Rotate-to-fullscreen gesture for videos.";
-
-const char kVideoRotateToFullscreenDescription[] =
-    "Enter/exit fullscreen when device is rotated to/from the orientation of "
-    "the video. Only on phones.";
-
-//  Enable default MediaSession flag
-
 #if !defined(OS_ANDROID)
 
 const char kEnableAudioFocusName[] = "Manage audio focus across tabs";
@@ -2664,15 +2517,6 @@
 
 #endif  // defined(OS_ANDROID)
 
-//  Media Remoting chrome://flags strings
-
-const char kMediaRemotingName[] = "Media Remoting during Cast Tab Mirroring";
-
-const char kMediaRemotingDescription[] =
-    "When Casting a tab to a remote device, enabling this turns on an "
-    "optimization that forwards the content bitstream directly to the remote "
-    "device when a video is fullscreened.";
-
 //  Play Services LSD permission prompt chrome://flags strings
 
 #if defined(OS_ANDROID)
@@ -2773,16 +2617,6 @@
 
 #endif  // defined(OS_CHROMEOS)
 
-const char kMojoLoadingName[] = "Use Mojo IPC for resource loading";
-
-const char kMojoLoadingDescription[] =
-    "Use Mojo IPC instead of traditional Chrome IPC for resource loading.";
-
-const char kModuleScriptsName[] = "Enable ECMAScript 6 modules";
-
-const char kModuleScriptsDescription[] =
-    "Enables ECMAScript 6 modules support in Blink.";
-
 #if defined(OS_ANDROID)
 
 const char kUseDdljsonApiName[] = "Use new ddljson API for Doodles";
@@ -2792,10 +2626,6 @@
 
 #endif  // defined(OS_ANDROID)
 
-const char kMemoryAblationName[] = "Memory ablation experiment";
-const char kMemoryAblationDescription[] =
-    "Allocates extra memory in the browser process.";
-
 #if defined(OS_ANDROID)
 
 const char kEnableCustomContextMenuName[] = "Enable custom context menu";
@@ -3032,74 +2862,6 @@
 
 #endif  // defined(OS_ANDROID)
 
-const char kOmniboxDisplayTitleForCurrentUrlName[] =
-    "Include title for the current URL in the omnibox";
-
-const char kOmniboxDisplayTitleForCurrentUrlDescription[] =
-    "In the event that the omnibox provides suggestions on-focus, the URL of "
-    "the current page is provided as the first suggestion without a title. "
-    "Enabling this flag causes the title to be displayed.";
-
-const char kOmniboxUIElideSuggestionUrlAfterHostName[] =
-    "Omnibox UI Elide Suggestion URL After Host";
-const char kOmniboxUIElideSuggestionUrlAfterHostDescription[] =
-    "Elides the path, query, and ref of suggested URLs in the Omnibox "
-    "dropdown.";
-
-const char kOmniboxUIHideSuggestionUrlSchemeName[] =
-    "Omnibox UI Hide Suggestion URL Scheme";
-const char kOmniboxUIHideSuggestionUrlSchemeDescription[] =
-    "Elides the schemes of suggested URLs in the Omnibox dropdown.";
-
-const char kOmniboxUIHideSuggestionUrlTrivialSubdomainsName[] =
-    "Omnibox UI Hide Suggestion URL Trivial Subdomains";
-const char kOmniboxUIHideSuggestionUrlTrivialSubdomainsDescription[] =
-    "Elides trivially informative subdomains from suggested URLs in the "
-    "Omnibox dropdown (e.g. www. and m.).";
-
-const char kOmniboxUIMaxAutocompleteMatchesName[] =
-    "Omnibox UI Max Autocomplete Matches";
-
-const char kOmniboxUIMaxAutocompleteMatchesDescription[] =
-    "Changes the maximum number of autocomplete matches displayed in the "
-    "Omnibox UI.";
-
-const char kOmniboxUINarrowDropdownName[] = "Omnibox UI Narrow Dropdown";
-
-const char kOmniboxUINarrowDropdownDescription[] =
-    "Makes the suggestions dropdown width match the omnibox width.";
-
-const char kOmniboxUIVerticalLayoutName[] = "Omnibox UI Vertical Layout";
-
-const char kOmniboxUIVerticalLayoutDescription[] =
-    "Displays Omnibox sugestions in 2 lines - title over origin.";
-
-const char kOmniboxUIVerticalMarginName[] = "Omnibox UI Vertical Margin";
-
-const char kOmniboxUIVerticalMarginDescription[] =
-    "Changes the vertical margin in the Omnibox UI.";
-
-const char kForceEffectiveConnectionTypeName[] =
-    "Override effective connection type";
-
-const char kForceEffectiveConnectionTypeDescription[] =
-    "Overrides the effective connection type of the current connection "
-    "returned by the network quality estimator.";
-
-const char kEffectiveConnectionTypeUnknownDescription[] = "Unknown";
-const char kEffectiveConnectionTypeOfflineDescription[] = "Offline";
-const char kEffectiveConnectionTypeSlow2GDescription[] = "Slow 2G";
-const char kEffectiveConnectionType2GDescription[] = "2G";
-const char kEffectiveConnectionType3GDescription[] = "3G";
-const char kEffectiveConnectionType4GDescription[] = "4G";
-
-const char kUseSuggestionsEvenIfFewFeatureName[] =
-    "Disable minimum for server-side tile suggestions on NTP.";
-
-const char kUseSuggestionsEvenIfFewFeatureDescription[] =
-    "Request server-side suggestions even if there are only very few of them "
-    "and use them for tiles on the New Tab Page.";
-
 #if defined(OS_WIN)
 
 // Name and description of the flag that enables D3D v-sync.
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index d1bc22a..51664acf 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -23,6 +23,9 @@
 // Sort flags in each section alphabetically by the k...Name constant. Follow
 // that by the k...Description constant and any special values associated with
 // that.
+//
+// Put #ifdefed flags in the appropriate section toward the bottom, don't
+// intersperse the file with ifdefs.
 
 namespace flag_descriptions {
 
@@ -46,6 +49,9 @@
 extern const char kAppBannersName[];
 extern const char kAppBannersDescription[];
 
+extern const char kAsyncImageDecodingName[];
+extern const char kAsyncImageDecodingDescription[];
+
 extern const char kAutoplayPolicyName[];
 extern const char kAutoplayPolicyDescription[];
 
@@ -160,9 +166,6 @@
 extern const char kEasyUnlockBluetoothLowEnergyDiscoveryName[];
 extern const char kEasyUnlockBluetoothLowEnergyDiscoveryDescription[];
 
-extern const char kEasyUnlockProximityDetectionName[];
-extern const char kEasyUnlockProximityDetectionDescription[];
-
 extern const char kEmbeddedExtensionOptionsName[];
 extern const char kEmbeddedExtensionOptionsDescription[];
 
@@ -779,12 +782,6 @@
 extern const char kV8CacheStrategiesForCacheStorageNormal[];
 extern const char kV8CacheStrategiesForCacheStorageAggressive[];
 
-extern const char kV8DisableIgnitionTurboName[];
-extern const char kV8DisableIgnitionTurboDescription[];
-
-extern const char kV8FutureName[];
-extern const char kV8FutureDescription[];
-
 extern const char kVibrateRequiresUserGestureName[];
 extern const char kVibrateRequiresUserGestureDescription[];
 
@@ -830,11 +827,6 @@
 extern const char kWebrtcStunOriginName[];
 extern const char kWebrtcStunOriginDescription[];
 
-#if BUILDFLAG(ENABLE_VR)
-extern const char kWebvrExperimentalRenderingName[];
-extern const char kWebvrExperimentalRenderingDescription[];
-#endif  // ENABLE_VR
-
 extern const char kWebvrName[];
 extern const char kWebvrDescription[];
 
@@ -988,19 +980,6 @@
 extern const char kEnableSpecialLocaleName[];
 extern const char kEnableSpecialLocaleDescription[];
 
-#if BUILDFLAG(ENABLE_VR)
-
-extern const char kEnableVrShellName[];
-extern const char kEnableVrShellDescription[];
-
-extern const char kVrCustomTabBrowsingName[];
-extern const char kVrCustomTabBrowsingDescription[];
-
-extern const char kWebVrAutopresentName[];
-extern const char kWebVrAutopresentDescription[];
-
-#endif  // BUILDFLAG(ENABLE_VR)
-
 extern const char kEnableWebapk[];
 extern const char kEnableWebapkDescription[];
 
@@ -1489,6 +1468,26 @@
 
 // Feature flags --------------------------------------------------------------
 
+#if BUILDFLAG(ENABLE_VR)
+
+#if defined(OS_ANDROID)
+
+extern const char kEnableVrShellName[];
+extern const char kEnableVrShellDescription[];
+
+extern const char kVrCustomTabBrowsingName[];
+extern const char kVrCustomTabBrowsingDescription[];
+
+extern const char kWebVrAutopresentName[];
+extern const char kWebVrAutopresentDescription[];
+
+#endif  // OS_ANDROID
+
+extern const char kWebvrExperimentalRenderingName[];
+extern const char kWebvrExperimentalRenderingDescription[];
+
+#endif  // ENABLE_VR
+
 #if !defined(DISABLE_NACL)
 
 extern const char kNaclDebugMaskName[];
diff --git a/chrome/browser/media/encrypted_media_browsertest.cc b/chrome/browser/media/encrypted_media_browsertest.cc
index 16243b2f..68352c0 100644
--- a/chrome/browser/media/encrypted_media_browsertest.cc
+++ b/chrome/browser/media/encrypted_media_browsertest.cc
@@ -778,12 +778,6 @@
 }
 
 IN_PROC_BROWSER_TEST_P(ECKEncryptedMediaTest, Renewal) {
-  // TODO(xhwang): Fix renewal time. See http://crbug.com/730762
-  if (IsUsingMojoCdm()) {
-    DVLOG(0) << "Skipping test; Not working with mojo CDM yet.";
-    return;
-  }
-
   TestPlaybackCase(kExternalClearKeyRenewalKeySystem, kNoSessionToLoad, kEnded);
 }
 
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
index f2be4a8..a381736 100644
--- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
+++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
@@ -13,6 +13,8 @@
 #include "base/metrics/histogram_macros.h"
 #include "base/metrics/sparse_histogram.h"
 #include "base/sys_info.h"
+#include "base/task_scheduler/post_task.h"
+#include "base/task_scheduler/task_traits.h"
 #include "base/threading/sequenced_worker_pool.h"
 #include "base/time/time.h"
 #include "build/build_config.h"
@@ -22,7 +24,6 @@
 #include "chrome/browser/mac/bluetooth_utility.h"
 #include "chrome/browser/shell_integration.h"
 #include "components/flags_ui/pref_service_flags_storage.h"
-#include "content/public/browser/browser_thread.h"
 #include "content/public/common/content_switches.h"
 #include "ui/base/touch/touch_device.h"
 #include "ui/base/ui_base_switches.h"
@@ -43,7 +44,6 @@
 #include "base/linux_util.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
-#include "base/task_scheduler/post_task.h"
 #include "base/version.h"
 #if defined(USE_X11)
 #include "ui/base/x/x11_util.h"
@@ -174,9 +174,9 @@
                               base::SysInfo::NumberOfProcessors());
 }
 
-// Called on the blocking pool some time after startup to avoid slowing down
+// Called on a background thread, with low priority to avoid slowing down
 // startup with metrics that aren't trivial to compute.
-void RecordStartupMetricsOnBlockingPool() {
+void RecordStartupMetrics() {
 #if defined(OS_WIN)
   GoogleUpdateSettings::RecordChromeUpdatePolicyHistograms();
 
@@ -459,7 +459,9 @@
   UMA_HISTOGRAM_ENUMERATION("Windows.IsPinnedToTaskbar", result, NUM_RESULTS);
 }
 
-// Records the pinned state of the current executable into a histogram.
+// Records the pinned state of the current executable into a histogram. Should
+// be called on a background thread, with low priority, to avoid slowing down
+// startup.
 void RecordIsPinnedToTaskbarHistogram() {
   shell_integration::win::GetIsPinnedToTaskbarState(
       base::Bind(&OnShellHandlerConnectionError),
@@ -504,9 +506,12 @@
   UMA_HISTOGRAM_ENUMERATION("Linux.WindowManager", GetLinuxWindowManager(),
                             UMA_LINUX_WINDOW_MANAGER_COUNT);
 #endif
+
+  const base::TaskTraits background_task_traits = {
+      base::MayBlock(), base::TaskPriority::BACKGROUND,
+      base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN};
 #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
-  base::PostTaskWithTraits(FROM_HERE,
-                           {base::MayBlock(), base::TaskPriority::BACKGROUND},
+  base::PostTaskWithTraits(FROM_HERE, background_task_traits,
                            base::BindOnce(&RecordLinuxDistro));
 #endif
 
@@ -528,16 +533,24 @@
   RecordMacMetrics();
 #endif  // defined(OS_MACOSX)
 
-  constexpr base::TimeDelta kStartupMetricsGatheringDelay =
-      base::TimeDelta::FromSeconds(45);
-  content::BrowserThread::GetBlockingPool()->PostDelayedTask(
-      FROM_HERE, base::BindOnce(&RecordStartupMetricsOnBlockingPool),
-      kStartupMetricsGatheringDelay);
 #if defined(OS_WIN)
-  content::BrowserThread::PostDelayedTask(
-      content::BrowserThread::IO, FROM_HERE,
-      base::Bind(&RecordIsPinnedToTaskbarHistogram),
-      kStartupMetricsGatheringDelay);
+  // RecordStartupMetrics calls into shell_integration::GetDefaultBrowser(),
+  // which requires a COM thread on Windows.
+  base::CreateCOMSTATaskRunnerWithTraits(background_task_traits)
+      ->PostTask(FROM_HERE, base::BindOnce(&RecordStartupMetrics));
+#else
+  base::PostTaskWithTraits(FROM_HERE, background_task_traits,
+                           base::BindOnce(&RecordStartupMetrics));
+#endif  // defined(OS_WIN)
+
+#if defined(OS_WIN)
+  // TODO(isherman): The delay below is currently needed to avoid (flakily)
+  // breaking some tests, including all of the ProcessMemoryMetricsEmitterTest
+  // tests. Figure out why there is a dependency and fix the tests.
+  base::CreateSequencedTaskRunnerWithTraits(background_task_traits)
+      ->PostDelayedTask(FROM_HERE,
+                        base::BindOnce(&RecordIsPinnedToTaskbarHistogram),
+                        base::TimeDelta::FromSeconds(45));
 #endif  // defined(OS_WIN)
 
   display_count_ = display::Screen::GetScreen()->GetNumDisplays();
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter.cc b/chrome/browser/metrics/process_memory_metrics_emitter.cc
index e9098cca..620ac406 100644
--- a/chrome/browser/metrics/process_memory_metrics_emitter.cc
+++ b/chrome/browser/metrics/process_memory_metrics_emitter.cc
@@ -8,6 +8,8 @@
 #include "base/trace_event/memory_dump_request_args.h"
 #include "content/public/common/service_manager_connection.h"
 #include "content/public/common/service_names.mojom.h"
+#include "services/metrics/public/cpp/ukm_entry_builder.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
 #include "services/service_manager/public/cpp/connector.h"
 
 using ProcessMemoryDumpPtr =
@@ -15,44 +17,96 @@
 
 namespace {
 
-void EmitBrowserMemoryMetrics(const ProcessMemoryDumpPtr& pmd) {
+void TryAddMetric(ukm::UkmEntryBuilder* builder,
+                  const char* metric_name,
+                  int64_t value) {
+  // Builder might be null if it was created before the UKMService was started.
+  // In that case, just no-op.
+  if (builder)
+    builder->AddMetric(metric_name, value);
+}
+
+void EmitBrowserMemoryMetrics(const ProcessMemoryDumpPtr& pmd,
+                              ukm::UkmEntryBuilder* builder) {
+  TryAddMetric(builder, "ProcessType",
+               static_cast<int64_t>(
+                   memory_instrumentation::mojom::ProcessType::BROWSER));
+
   UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Browser2.Resident",
                                 pmd->os_dump->resident_set_kb / 1024);
+  TryAddMetric(builder, "Resident", pmd->os_dump->resident_set_kb / 1024);
+
   UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Browser2.Malloc",
                                 pmd->chrome_dump.malloc_total_kb / 1024);
+  TryAddMetric(builder, "Malloc", pmd->chrome_dump.malloc_total_kb / 1024);
+
   UMA_HISTOGRAM_MEMORY_LARGE_MB(
       "Memory.Experimental.Browser2.PrivateMemoryFootprint",
       pmd->os_dump->private_footprint_kb / 1024);
+  TryAddMetric(builder, "PrivateMemoryFootprint",
+               pmd->os_dump->private_footprint_kb / 1024);
 }
 
-void EmitRendererMemoryMetrics(const ProcessMemoryDumpPtr& pmd) {
+void EmitRendererMemoryMetrics(const ProcessMemoryDumpPtr& pmd,
+                               ukm::UkmEntryBuilder* builder) {
+  TryAddMetric(builder, "ProcessType",
+               static_cast<int64_t>(
+                   memory_instrumentation::mojom::ProcessType::RENDERER));
+
   UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Renderer2.Resident",
                                 pmd->os_dump->resident_set_kb / 1024);
+  TryAddMetric(builder, "Resident", pmd->os_dump->resident_set_kb / 1024);
+
+  UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Renderer2.Malloc",
+                                pmd->chrome_dump.malloc_total_kb / 1024);
+  TryAddMetric(builder, "Malloc", pmd->chrome_dump.malloc_total_kb / 1024);
+
   UMA_HISTOGRAM_MEMORY_LARGE_MB(
       "Memory.Experimental.Renderer2.PrivateMemoryFootprint",
       pmd->os_dump->private_footprint_kb / 1024);
-  UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Renderer2.Malloc",
-                                pmd->chrome_dump.malloc_total_kb / 1024);
+  TryAddMetric(builder, "PrivateMemoryFootprint",
+               pmd->os_dump->private_footprint_kb / 1024);
+
   UMA_HISTOGRAM_MEMORY_LARGE_MB(
       "Memory.Experimental.Renderer2.PartitionAlloc",
       pmd->chrome_dump.partition_alloc_total_kb / 1024);
+  TryAddMetric(builder, "PartitionAlloc",
+               pmd->chrome_dump.partition_alloc_total_kb / 1024);
+
   UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Renderer2.BlinkGC",
                                 pmd->chrome_dump.blink_gc_total_kb / 1024);
+  TryAddMetric(builder, "BlinkGC", pmd->chrome_dump.blink_gc_total_kb / 1024);
+
   UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Renderer2.V8",
                                 pmd->chrome_dump.v8_total_kb / 1024);
+  TryAddMetric(builder, "V8", pmd->chrome_dump.v8_total_kb / 1024);
 }
 
-void EmitGpuMemoryMetrics(const ProcessMemoryDumpPtr& pmd) {
+void EmitGpuMemoryMetrics(const ProcessMemoryDumpPtr& pmd,
+                          ukm::UkmEntryBuilder* builder) {
+  TryAddMetric(
+      builder, "ProcessType",
+      static_cast<int64_t>(memory_instrumentation::mojom::ProcessType::GPU));
+
   UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Gpu2.Resident",
                                 pmd->os_dump->resident_set_kb / 1024);
+  TryAddMetric(builder, "Resident", pmd->os_dump->resident_set_kb / 1024);
+
   UMA_HISTOGRAM_MEMORY_LARGE_MB("Memory.Experimental.Gpu2.Malloc",
                                 pmd->chrome_dump.malloc_total_kb / 1024);
+  TryAddMetric(builder, "Malloc", pmd->chrome_dump.malloc_total_kb / 1024);
+
   UMA_HISTOGRAM_MEMORY_LARGE_MB(
       "Memory.Experimental.Gpu2.CommandBuffer",
       pmd->chrome_dump.command_buffer_total_kb / 1024);
+  TryAddMetric(builder, "CommandBuffer",
+               pmd->chrome_dump.command_buffer_total_kb / 1024);
+
   UMA_HISTOGRAM_MEMORY_LARGE_MB(
       "Memory.Experimental.Gpu2.PrivateMemoryFootprint",
       pmd->os_dump->private_footprint_kb / 1024);
+  TryAddMetric(builder, "PrivateMemoryFootprint",
+               pmd->os_dump->private_footprint_kb / 1024);
 }
 
 }  // namespace
@@ -77,6 +131,16 @@
 
 ProcessMemoryMetricsEmitter::~ProcessMemoryMetricsEmitter() {}
 
+std::unique_ptr<ukm::UkmEntryBuilder>
+ProcessMemoryMetricsEmitter::CreateUkmBuilder(const char* event_name) {
+  ukm::UkmRecorder* ukm_recorder = ukm::UkmRecorder::Get();
+  if (!ukm_recorder)
+    return nullptr;
+
+  const int32_t source_id = ukm_recorder->GetNewSourceID();
+  return ukm_recorder->GetEntryBuilder(source_id, event_name);
+}
+
 void ProcessMemoryMetricsEmitter::ReceivedMemoryDump(
     bool success,
     uint64_t dump_guid,
@@ -89,15 +153,23 @@
   uint32_t private_footprint_total_kb = 0;
   for (const ProcessMemoryDumpPtr& pmd : ptr->process_dumps) {
     private_footprint_total_kb += pmd->os_dump->private_footprint_kb;
+
+    // Populate a new entry for each ProcessMemoryDumpPtr in the global dump,
+    // annotating each entry with the dump GUID so that entries in the same
+    // global dump can be correlated with each other.
+    // TODO(jchinlee): Add URLs.
+    std::unique_ptr<ukm::UkmEntryBuilder> builder =
+        CreateUkmBuilder("Memory.Experimental");
+
     switch (pmd->process_type) {
       case memory_instrumentation::mojom::ProcessType::BROWSER:
-        EmitBrowserMemoryMetrics(pmd);
+        EmitBrowserMemoryMetrics(pmd, builder.get());
         break;
       case memory_instrumentation::mojom::ProcessType::RENDERER:
-        EmitRendererMemoryMetrics(pmd);
+        EmitRendererMemoryMetrics(pmd, builder.get());
         break;
       case memory_instrumentation::mojom::ProcessType::GPU:
-        EmitGpuMemoryMetrics(pmd);
+        EmitGpuMemoryMetrics(pmd, builder.get());
         break;
       case memory_instrumentation::mojom::ProcessType::UTILITY:
       case memory_instrumentation::mojom::ProcessType::PLUGIN:
@@ -108,4 +180,9 @@
   UMA_HISTOGRAM_MEMORY_LARGE_MB(
       "Memory.Experimental.Total2.PrivateMemoryFootprint",
       private_footprint_total_kb / 1024);
+
+  std::unique_ptr<ukm::UkmEntryBuilder> builder =
+      CreateUkmBuilder("Memory.Experimental");
+  TryAddMetric(builder.get(), "Total2.PrivateMemoryFootprint",
+               private_footprint_total_kb / 1024);
 }
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter.h b/chrome/browser/metrics/process_memory_metrics_emitter.h
index 0358a8f..fa91d276 100644
--- a/chrome/browser/metrics/process_memory_metrics_emitter.h
+++ b/chrome/browser/metrics/process_memory_metrics_emitter.h
@@ -8,6 +8,10 @@
 #include "base/memory/ref_counted.h"
 #include "services/resource_coordinator/public/interfaces/memory_instrumentation/memory_instrumentation.mojom.h"
 
+namespace ukm {
+class UkmEntryBuilder;
+}
+
 // This class asynchronously fetches memory metrics for each process, and then
 // emits UMA metrics from those metrics.
 // Each instance is self-owned, and will delete itself once it has finished
@@ -35,6 +39,9 @@
  private:
   friend class base::RefCountedThreadSafe<ProcessMemoryMetricsEmitter>;
 
+  std::unique_ptr<ukm::UkmEntryBuilder> CreateUkmBuilder(
+      const char* event_name);
+
   memory_instrumentation::mojom::CoordinatorPtr coordinator_;
 
   DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMetricsEmitter);
diff --git a/chrome/browser/metrics/process_memory_metrics_emitter_unittest.cc b/chrome/browser/metrics/process_memory_metrics_emitter_unittest.cc
new file mode 100644
index 0000000..1b27d2c8
--- /dev/null
+++ b/chrome/browser/metrics/process_memory_metrics_emitter_unittest.cc
@@ -0,0 +1,265 @@
+// 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/metrics/process_memory_metrics_emitter.h"
+
+#include "base/containers/flat_map.h"
+#include "base/memory/ref_counted.h"
+#include "components/ukm/test_ukm_recorder.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using GlobalMemoryDumpPtr = memory_instrumentation::mojom::GlobalMemoryDumpPtr;
+using ProcessMemoryDumpPtr =
+    memory_instrumentation::mojom::ProcessMemoryDumpPtr;
+using OSMemDumpPtr = memory_instrumentation::mojom::OSMemDumpPtr;
+using ProcessType = memory_instrumentation::mojom::ProcessType;
+
+namespace {
+
+// Provide fake to surface ReceivedMemoryDump to public visibility.
+class ProcessMemoryMetricsEmitterFake : public ProcessMemoryMetricsEmitter {
+ public:
+  ProcessMemoryMetricsEmitterFake() {}
+
+  void ReceivedMemoryDump(
+      bool success,
+      uint64_t dump_guid,
+      memory_instrumentation::mojom::GlobalMemoryDumpPtr ptr) override {
+    ProcessMemoryMetricsEmitter::ReceivedMemoryDump(success, dump_guid,
+                                                    std::move(ptr));
+  }
+
+ private:
+  ~ProcessMemoryMetricsEmitterFake() override {}
+
+  DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMetricsEmitterFake);
+};
+
+void PopulateBrowserMetrics(GlobalMemoryDumpPtr& global_dump,
+                            base::flat_map<const char*, int64_t>& metrics_mb) {
+  ProcessMemoryDumpPtr pmd(
+      memory_instrumentation::mojom::ProcessMemoryDump::New());
+  pmd->process_type = ProcessType::BROWSER;
+  pmd->chrome_dump.malloc_total_kb = metrics_mb["Malloc"] * 1024;
+  OSMemDumpPtr os_dump(memory_instrumentation::mojom::OSMemDump::New(
+      metrics_mb["Resident"] * 1024,
+      metrics_mb["PrivateMemoryFootprint"] * 1024));
+  pmd->os_dump = std::move(os_dump);
+  global_dump->process_dumps.push_back(std::move(pmd));
+}
+
+base::flat_map<const char*, int64_t> GetExpectedBrowserMetrics() {
+  return base::flat_map<const char*, int64_t>(
+      {
+          {"ProcessType", static_cast<int64_t>(ProcessType::BROWSER)},
+          {"Resident", 10},
+          {"Malloc", 20},
+          {"PrivateMemoryFootprint", 30},
+      },
+      base::KEEP_FIRST_OF_DUPES);
+}
+
+void PopulateRendererMetrics(GlobalMemoryDumpPtr& global_dump,
+                             base::flat_map<const char*, int64_t>& metrics_mb) {
+  ProcessMemoryDumpPtr pmd(
+      memory_instrumentation::mojom::ProcessMemoryDump::New());
+  pmd->process_type = ProcessType::RENDERER;
+  pmd->chrome_dump.malloc_total_kb = metrics_mb["Malloc"] * 1024;
+  pmd->chrome_dump.partition_alloc_total_kb =
+      metrics_mb["PartitionAlloc"] * 1024;
+  pmd->chrome_dump.blink_gc_total_kb = metrics_mb["BlinkGC"] * 1024;
+  pmd->chrome_dump.v8_total_kb = metrics_mb["V8"] * 1024;
+  OSMemDumpPtr os_dump(memory_instrumentation::mojom::OSMemDump::New(
+      metrics_mb["Resident"] * 1024,
+      metrics_mb["PrivateMemoryFootprint"] * 1024));
+  pmd->os_dump = std::move(os_dump);
+  global_dump->process_dumps.push_back(std::move(pmd));
+}
+
+base::flat_map<const char*, int64_t> GetExpectedRendererMetrics() {
+  return base::flat_map<const char*, int64_t>(
+      {
+          {"ProcessType", static_cast<int64_t>(ProcessType::RENDERER)},
+          {"Resident", 110},
+          {"Malloc", 120},
+          {"PrivateMemoryFootprint", 130},
+          {"PartitionAlloc", 140},
+          {"BlinkGC", 150},
+          {"V8", 160},
+      },
+      base::KEEP_FIRST_OF_DUPES);
+}
+
+void PopulateGpuMetrics(GlobalMemoryDumpPtr& global_dump,
+                        base::flat_map<const char*, int64_t>& metrics_mb) {
+  ProcessMemoryDumpPtr pmd(
+      memory_instrumentation::mojom::ProcessMemoryDump::New());
+  pmd->process_type = ProcessType::GPU;
+  pmd->chrome_dump.malloc_total_kb = metrics_mb["Malloc"] * 1024;
+  pmd->chrome_dump.command_buffer_total_kb = metrics_mb["CommandBuffer"] * 1024;
+  OSMemDumpPtr os_dump(memory_instrumentation::mojom::OSMemDump::New(
+      metrics_mb["Resident"] * 1024,
+      metrics_mb["PrivateMemoryFootprint"] * 1024));
+  pmd->os_dump = std::move(os_dump);
+  global_dump->process_dumps.push_back(std::move(pmd));
+}
+
+base::flat_map<const char*, int64_t> GetExpectedGpuMetrics() {
+  return base::flat_map<const char*, int64_t>(
+      {
+          {"ProcessType", static_cast<int64_t>(ProcessType::GPU)},
+          {"Resident", 210},
+          {"Malloc", 220},
+          {"PrivateMemoryFootprint", 230},
+          {"CommandBuffer", 240},
+      },
+      base::KEEP_FIRST_OF_DUPES);
+}
+
+void PopulateMetrics(GlobalMemoryDumpPtr& global_dump,
+                     ProcessType ptype,
+                     base::flat_map<const char*, int64_t>& metrics_mb) {
+  switch (ptype) {
+    case ProcessType::BROWSER:
+      PopulateBrowserMetrics(global_dump, metrics_mb);
+      return;
+    case ProcessType::RENDERER:
+      PopulateRendererMetrics(global_dump, metrics_mb);
+      return;
+    case ProcessType::GPU:
+      PopulateGpuMetrics(global_dump, metrics_mb);
+      return;
+    case ProcessType::UTILITY:
+    case ProcessType::PLUGIN:
+    case ProcessType::OTHER:
+      break;
+  }
+
+  // We shouldn't reach here.
+  FAIL() << "Unknown process type case " << ptype << ".";
+}
+
+base::flat_map<const char*, int64_t> GetExpectedProcessMetrics(
+    ProcessType ptype) {
+  switch (ptype) {
+    case ProcessType::BROWSER:
+      return GetExpectedBrowserMetrics();
+    case ProcessType::RENDERER:
+      return GetExpectedRendererMetrics();
+    case ProcessType::GPU:
+      return GetExpectedGpuMetrics();
+    case ProcessType::UTILITY:
+    case ProcessType::PLUGIN:
+    case ProcessType::OTHER:
+      break;
+  }
+
+  // We shouldn't reach here.
+  CHECK(false);
+  return base::flat_map<const char*, int64_t>();
+}
+
+}  // namespace
+
+class ProcessMemoryMetricsEmitterTest
+    : public testing::TestWithParam<ProcessType> {
+ public:
+  ProcessMemoryMetricsEmitterTest() {}
+  ~ProcessMemoryMetricsEmitterTest() override {}
+
+ protected:
+  void CheckMemoryUkmEntryMetrics(
+      size_t entry_num,
+      base::flat_map<const char*, int64_t> expected) {
+    const ukm::mojom::UkmEntry* entry = test_ukm_recorder_.GetEntry(entry_num);
+    CHECK(entry != nullptr);
+    EXPECT_EQ(expected.size(), entry->metrics.size());
+    for (auto it = expected.begin(); it != expected.end(); ++it) {
+      const ukm::mojom::UkmMetric* actual =
+          test_ukm_recorder_.FindMetric(entry, it->first);
+      CHECK(actual != nullptr);
+      EXPECT_EQ(it->second, actual->value);
+    }
+  }
+
+  ukm::TestUkmRecorder test_ukm_recorder_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ProcessMemoryMetricsEmitterTest);
+};
+
+TEST_P(ProcessMemoryMetricsEmitterTest, CollectsSingleProcessUKMs) {
+  base::flat_map<const char*, int64_t> expected_metrics =
+      GetExpectedProcessMetrics(GetParam());
+  uint64_t dump_guid = 333;
+
+  GlobalMemoryDumpPtr global_dump(
+      memory_instrumentation::mojom::GlobalMemoryDump::New());
+  PopulateMetrics(global_dump, GetParam(), expected_metrics);
+
+  scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter(
+      new ProcessMemoryMetricsEmitterFake());
+  emitter->ReceivedMemoryDump(true, dump_guid, std::move(global_dump));
+
+  EXPECT_EQ(2u, test_ukm_recorder_.entries_count());
+  CheckMemoryUkmEntryMetrics(0, expected_metrics);
+}
+
+INSTANTIATE_TEST_CASE_P(SinglePtype,
+                        ProcessMemoryMetricsEmitterTest,
+                        testing::Values(ProcessType::BROWSER,
+                                        ProcessType::RENDERER,
+                                        ProcessType::GPU));
+
+TEST_F(ProcessMemoryMetricsEmitterTest, CollectsManyProcessUKMsSingleDump) {
+  std::vector<ProcessType> entries_ptypes = {
+      ProcessType::BROWSER, ProcessType::RENDERER, ProcessType::GPU,
+      ProcessType::GPU,     ProcessType::RENDERER, ProcessType::BROWSER,
+  };
+  uint64_t dump_guid = 333;
+
+  GlobalMemoryDumpPtr global_dump(
+      memory_instrumentation::mojom::GlobalMemoryDump::New());
+  std::vector<base::flat_map<const char*, int64_t>> entries_metrics;
+  for (const auto& ptype : entries_ptypes) {
+    auto expected_metrics = GetExpectedProcessMetrics(ptype);
+    PopulateMetrics(global_dump, ptype, expected_metrics);
+    entries_metrics.push_back(expected_metrics);
+  }
+
+  scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter(
+      new ProcessMemoryMetricsEmitterFake());
+  emitter->ReceivedMemoryDump(true, dump_guid, std::move(global_dump));
+
+  EXPECT_EQ(7u, test_ukm_recorder_.entries_count());
+  for (size_t i = 0; i < entries_ptypes.size(); ++i) {
+    CheckMemoryUkmEntryMetrics(i, entries_metrics[i]);
+  }
+}
+
+TEST_F(ProcessMemoryMetricsEmitterTest, CollectsManyProcessUKMsManyDumps) {
+  std::vector<std::vector<ProcessType>> entries_ptypes = {
+      {ProcessType::BROWSER, ProcessType::RENDERER, ProcessType::GPU},
+      {ProcessType::GPU, ProcessType::RENDERER, ProcessType::BROWSER},
+  };
+
+  std::vector<base::flat_map<const char*, int64_t>> entries_metrics;
+  scoped_refptr<ProcessMemoryMetricsEmitterFake> emitter(
+      new ProcessMemoryMetricsEmitterFake());
+  for (int i = 0; i < 2; ++i) {
+    GlobalMemoryDumpPtr global_dump(
+        memory_instrumentation::mojom::GlobalMemoryDump::New());
+    for (const auto& ptype : entries_ptypes[i]) {
+      auto expected_metrics = GetExpectedProcessMetrics(ptype);
+      PopulateMetrics(global_dump, ptype, expected_metrics);
+      entries_metrics.push_back(expected_metrics);
+    }
+    emitter->ReceivedMemoryDump(true, i, std::move(global_dump));
+  }
+
+  EXPECT_EQ(8u, test_ukm_recorder_.entries_count());
+  for (size_t i = 0; i < entries_ptypes.size(); ++i) {
+    CheckMemoryUkmEntryMetrics(i, entries_metrics[i]);
+  }
+}
diff --git a/chrome/browser/ntp_snippets/download_suggestions_provider.cc b/chrome/browser/ntp_snippets/download_suggestions_provider.cc
index c3bdf67..8d0e677 100644
--- a/chrome/browser/ntp_snippets/download_suggestions_provider.cc
+++ b/chrome/browser/ntp_snippets/download_suggestions_provider.cc
@@ -383,12 +383,11 @@
 }
 
 void DownloadSuggestionsProvider::OfflinePageDeleted(
-    int64_t offline_id,
-    const offline_pages::ClientId& client_id) {
+    const offline_pages::OfflinePageModel::DeletedPageInfo& page_info) {
   DCHECK(offline_page_model_);
   if (IsClientIdForOfflinePageDownload(
-          offline_page_model_->GetPolicyController(), client_id)) {
-    InvalidateSuggestion(GetOfflinePagePerCategoryID(offline_id));
+          offline_page_model_->GetPolicyController(), page_info.client_id)) {
+    InvalidateSuggestion(GetOfflinePagePerCategoryID(page_info.offline_id));
   }
 }
 
diff --git a/chrome/browser/ntp_snippets/download_suggestions_provider.h b/chrome/browser/ntp_snippets/download_suggestions_provider.h
index 951be12..c62f8e4 100644
--- a/chrome/browser/ntp_snippets/download_suggestions_provider.h
+++ b/chrome/browser/ntp_snippets/download_suggestions_provider.h
@@ -92,8 +92,9 @@
   void OfflinePageAdded(
       offline_pages::OfflinePageModel* model,
       const offline_pages::OfflinePageItem& added_page) override;
-  void OfflinePageDeleted(int64_t offline_id,
-                          const offline_pages::ClientId& client_id) override;
+  void OfflinePageDeleted(
+      const offline_pages::OfflinePageModel::DeletedPageInfo& page_info)
+      override;
 
   // content::DownloadManager::Observer implementation.
   void OnDownloadCreated(content::DownloadManager* manager,
diff --git a/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc b/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc
index aa5f26e..ba5aa5fb 100644
--- a/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc
+++ b/chrome/browser/ntp_snippets/download_suggestions_provider_unittest.cc
@@ -324,7 +324,9 @@
 
   void FireOfflinePageDeleted(const OfflinePageItem& item) {
     DCHECK(provider_);
-    provider_->OfflinePageDeleted(item.offline_id, item.client_id);
+    offline_pages::OfflinePageModel::DeletedPageInfo info(
+        item.offline_id, item.client_id, item.request_origin);
+    provider_->OfflinePageDeleted(info);
   }
 
   void FireDownloadCreated(DownloadItem* item) {
diff --git a/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.cc b/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.cc
index a2d49a9..2eeeb74 100644
--- a/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.cc
+++ b/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.cc
@@ -26,6 +26,11 @@
     downloader->OnDownloadServiceReady();
 }
 
+void OfflinePrefetchDownloadClient::OnServiceUnavailable() {
+  // TODO(dtrainor, jianli): Handle service initialization failures.  This could
+  // potentially just drop all pending start requests.
+}
+
 download::Client::ShouldDownload
 OfflinePrefetchDownloadClient::OnDownloadStarted(
     const std::string& guid,
diff --git a/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.h b/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.h
index 3a258ff..197c22f 100644
--- a/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.h
+++ b/chrome/browser/offline_pages/prefetch/offline_prefetch_download_client.h
@@ -25,6 +25,7 @@
   // Overridden from Client:
   void OnServiceInitialized(
       const std::vector<std::string>& outstanding_download_guids) override;
+  void OnServiceUnavailable() override;
   download::Client::ShouldDownload OnDownloadStarted(
       const std::string& guid,
       const std::vector<GURL>& url_chain,
diff --git a/chrome/browser/page_load_metrics/observers/local_network_requests_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/local_network_requests_page_load_metrics_observer.cc
index 11066e7..bc2ae429 100644
--- a/chrome/browser/page_load_metrics/observers/local_network_requests_page_load_metrics_observer.cc
+++ b/chrome/browser/page_load_metrics/observers/local_network_requests_page_load_metrics_observer.cc
@@ -197,36 +197,35 @@
   if (histogram_names.Get().empty()) {
     histogram_names.Get()[internal::DOMAIN_TYPE_PUBLIC]
                          [internal::RESOURCE_TYPE_PRIVATE][true] =
-        "LocalNetworkRequests.PublicPage.PrivateRequestCount.Successful";
+        "LocalNetworkRequests.PublicPage.PrivateRequests.Successful";
     histogram_names.Get()[internal::DOMAIN_TYPE_PUBLIC]
                          [internal::RESOURCE_TYPE_PRIVATE][false] =
-        "LocalNetworkRequests.PublicPage.PrivateRequestCount.Failed";
+        "LocalNetworkRequests.PublicPage.PrivateRequests.Failed";
     histogram_names.Get()[internal::DOMAIN_TYPE_PUBLIC]
                          [internal::RESOURCE_TYPE_ROUTER][true] =
-        "LocalNetworkRequests.PublicPage.RouterRequestCount.Successful";
+        "LocalNetworkRequests.PublicPage.RouterRequests.Successful";
     histogram_names.Get()[internal::DOMAIN_TYPE_PUBLIC]
                          [internal::RESOURCE_TYPE_ROUTER][false] =
-        "LocalNetworkRequests.PublicPage.RouterRequestCount.Failed";
+        "LocalNetworkRequests.PublicPage.RouterRequests.Failed";
 
     histogram_names.Get()[internal::DOMAIN_TYPE_PRIVATE]
                          [internal::RESOURCE_TYPE_PUBLIC][true] =
-        "LocalNetworkRequests.PrivatePage.PublicRequestCount.Successful";
+        "LocalNetworkRequests.PrivatePage.PublicRequests.Successful";
     histogram_names.Get()[internal::DOMAIN_TYPE_PRIVATE]
                          [internal::RESOURCE_TYPE_PUBLIC][false] =
-        "LocalNetworkRequests.PrivatePage.PublicRequestCount.Failed";
+        "LocalNetworkRequests.PrivatePage.PublicRequests.Failed";
     histogram_names.Get()[internal::DOMAIN_TYPE_PRIVATE]
                          [internal::RESOURCE_TYPE_LOCAL_SAME_SUBNET][true] =
-        "LocalNetworkRequests.PrivatePage.SameSubnetRequestCount.Successful";
+        "LocalNetworkRequests.PrivatePage.SameSubnetRequests.Successful";
     histogram_names.Get()[internal::DOMAIN_TYPE_PRIVATE]
                          [internal::RESOURCE_TYPE_LOCAL_SAME_SUBNET][false] =
-        "LocalNetworkRequests.PrivatePage.SameSubnetRequestCount.Failed";
+        "LocalNetworkRequests.PrivatePage.SameSubnetRequests.Failed";
     histogram_names.Get()[internal::DOMAIN_TYPE_PRIVATE]
                          [internal::RESOURCE_TYPE_LOCAL_DIFF_SUBNET][true] =
-        "LocalNetworkRequests.PrivatePage."
-        "DifferentSubnetRequestCount.Successful";
+        "LocalNetworkRequests.PrivatePage.DifferentSubnetRequests.Successful";
     histogram_names.Get()[internal::DOMAIN_TYPE_PRIVATE]
                          [internal::RESOURCE_TYPE_LOCAL_DIFF_SUBNET][false] =
-        "LocalNetworkRequests.PrivatePage.DifferentSubnetRequestCount.Failed";
+        "LocalNetworkRequests.PrivatePage.DifferentSubnetRequests.Failed";
   }
 
   return histogram_names.Get();
@@ -243,85 +242,65 @@
   if (histogram_names.Get().empty()) {
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PUBLIC][internal::PORT_TYPE_WEB][true] =
-        "LocalNetworkRequests.PublicPage.Localhost."
-        "WebRequestCount.Successful";
+        "LocalNetworkRequests.PublicPage.Localhost.WebRequests.Successful";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PUBLIC][internal::PORT_TYPE_WEB][false] =
-        "LocalNetworkRequests.PublicPage.Localhost."
-        "WebRequestCount.Failed";
+        "LocalNetworkRequests.PublicPage.Localhost.WebRequests.Failed";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PUBLIC][internal::PORT_TYPE_DB][true] =
-        "LocalNetworkRequests.PublicPage.Localhost."
-        "DatabaseRequestCount.Successful";
+        "LocalNetworkRequests.PublicPage.Localhost.DbRequests.Successful";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PUBLIC][internal::PORT_TYPE_DB][false] =
-        "LocalNetworkRequests.PublicPage.Localhost."
-        "DatabaseRequestCount.Failed";
+        "LocalNetworkRequests.PublicPage.Localhost.DbRequests.Failed";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PUBLIC][internal::PORT_TYPE_PRINT][true] =
-        "LocalNetworkRequests.PublicPage.Localhost."
-        "PrinterRequestCount.Successful";
+        "LocalNetworkRequests.PublicPage.Localhost.PrinterRequests.Successful";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PUBLIC][internal::PORT_TYPE_PRINT][false] =
-        "LocalNetworkRequests.PublicPage.Localhost."
-        "PrinterRequestCount.Failed";
+        "LocalNetworkRequests.PublicPage.Localhost.PrinterRequests.Failed";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PUBLIC][internal::PORT_TYPE_DEV][true] =
-        "LocalNetworkRequests.PublicPage.Localhost."
-        "DevelopmentRequestCount.Successful";
+        "LocalNetworkRequests.PublicPage.Localhost.DevRequests.Successful";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PUBLIC][internal::PORT_TYPE_DEV][false] =
-        "LocalNetworkRequests.PublicPage.Localhost."
-        "DevelopmentRequestCount.Failed";
+        "LocalNetworkRequests.PublicPage.Localhost.DevRequests.Failed";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PUBLIC][internal::PORT_TYPE_OTHER][true] =
-        "LocalNetworkRequests.PublicPage.Localhost."
-        "OtherRequestCount.Successful";
+        "LocalNetworkRequests.PublicPage.Localhost.OtherRequests.Successful";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PUBLIC][internal::PORT_TYPE_OTHER][false] =
-        "LocalNetworkRequests.PublicPage.Localhost."
-        "OtherRequestCount.Failed";
+        "LocalNetworkRequests.PublicPage.Localhost.OtherRequests.Failed";
 
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PRIVATE][internal::PORT_TYPE_WEB][true] =
-        "LocalNetworkRequests.PrivatePage.Localhost."
-        "WebRequestCount.Successful";
+        "LocalNetworkRequests.PrivatePage.Localhost.WebRequests.Successful";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PRIVATE][internal::PORT_TYPE_WEB][false] =
-        "LocalNetworkRequests.PrivatePage.Localhost."
-        "WebRequestCount.Failed";
+        "LocalNetworkRequests.PrivatePage.Localhost.WebRequests.Failed";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PRIVATE][internal::PORT_TYPE_DB][true] =
-        "LocalNetworkRequests.PrivatePage.Localhost."
-        "DatabaseRequestCount.Successful";
+        "LocalNetworkRequests.PrivatePage.Localhost.DbRequests.Successful";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PRIVATE][internal::PORT_TYPE_DB][false] =
-        "LocalNetworkRequests.PrivatePage.Localhost."
-        "DatabaseRequestCount.Failed";
+        "LocalNetworkRequests.PrivatePage.Localhost.DbRequests.Failed";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PRIVATE][internal::PORT_TYPE_PRINT][true] =
-        "LocalNetworkRequests.PrivatePage.Localhost."
-        "PrinterRequestCount.Successful";
+        "LocalNetworkRequests.PrivatePage.Localhost.PrinterRequests.Successful";
     histogram_names.Get()[internal::DOMAIN_TYPE_PRIVATE]
                          [internal::PORT_TYPE_PRINT][false] =
-        "LocalNetworkRequests.PrivatePage.Localhost."
-        "PrinterRequestCount.Failed";
+        "LocalNetworkRequests.PrivatePage.Localhost.PrinterRequests.Failed";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PRIVATE][internal::PORT_TYPE_DEV][true] =
-        "LocalNetworkRequests.PrivatePage.Localhost."
-        "DevelopmentRequestCount.Successful";
+        "LocalNetworkRequests.PrivatePage.Localhost.DevRequests.Successful";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PRIVATE][internal::PORT_TYPE_DEV][false] =
-        "LocalNetworkRequests.PrivatePage.Localhost."
-        "DevelopmentRequestCount.Failed";
+        "LocalNetworkRequests.PrivatePage.Localhost.DevRequests.Failed";
     histogram_names
         .Get()[internal::DOMAIN_TYPE_PRIVATE][internal::PORT_TYPE_OTHER][true] =
-        "LocalNetworkRequests.PrivatePage.Localhost."
-        "OtherRequestCount.Successful";
+        "LocalNetworkRequests.PrivatePage.Localhost.OtherRequests.Successful";
     histogram_names.Get()[internal::DOMAIN_TYPE_PRIVATE]
                          [internal::PORT_TYPE_OTHER][false] =
-        "LocalNetworkRequests.PrivatePage.Localhost."
-        "OtherRequestCount.Failed";
+        "LocalNetworkRequests.PrivatePage.Localhost.OtherRequests.Failed";
   }
 
   return histogram_names.Get();
diff --git a/chrome/browser/policy/policy_browsertest.cc b/chrome/browser/policy/policy_browsertest.cc
index be87bdd..fb5062f1 100644
--- a/chrome/browser/policy/policy_browsertest.cc
+++ b/chrome/browser/policy/policy_browsertest.cc
@@ -63,7 +63,6 @@
 #include "chrome/browser/media/router/media_router_feature.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
 #include "chrome/browser/media/webrtc/media_stream_devices_controller.h"
-#include "chrome/browser/metrics/variations/chrome_variations_service_client.h"
 #include "chrome/browser/net/prediction_options.h"
 #include "chrome/browser/net/url_request_mock_util.h"
 #include "chrome/browser/permissions/permission_request_manager.h"
@@ -4084,6 +4083,10 @@
 // started.
 class PolicyVariationsServiceTest : public PolicyTest {
  public:
+  PolicyVariationsServiceTest() {
+    variations::VariationsService::EnableForTesting();
+  }
+
   void SetUpInProcessBrowserTestFixture() override {
     PolicyTest::SetUpInProcessBrowserTestFixture();
     PolicyMap policies;
@@ -4098,15 +4101,9 @@
   const std::string default_variations_url =
       variations::VariationsService::GetDefaultVariationsServerURLForTesting();
 
-  // g_browser_process->variations_service() is null by default in Chromium
-  // builds, so construct a VariationsService locally instead.
-  std::unique_ptr<variations::VariationsService> service =
-      variations::VariationsService::CreateForTesting(
-          base::MakeUnique<ChromeVariationsServiceClient>(),
-          g_browser_process->local_state());
-
-  const GURL url = service->GetVariationsServerURL(
-      g_browser_process->local_state(), std::string());
+  const GURL url =
+      g_browser_process->variations_service()->GetVariationsServerURL(
+          g_browser_process->local_state(), std::string());
   EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url,
                                base::CompareCase::SENSITIVE));
   std::string value;
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc
index 07850f5..561601347 100644
--- a/chrome/browser/printing/print_job_worker.cc
+++ b/chrome/browser/printing/print_job_worker.cc
@@ -114,7 +114,11 @@
 PrintJobWorker::PrintJobWorker(int render_process_id,
                                int render_frame_id,
                                PrintJobWorkerOwner* owner)
-    : owner_(owner), thread_("Printing_Worker"), weak_factory_(this) {
+    : render_process_id_(render_process_id),
+      render_frame_id_(render_frame_id),
+      owner_(owner),
+      thread_("Printing_Worker"),
+      weak_factory_(this) {
   // The object is created in the IO thread.
   DCHECK(owner_->RunsTasksInCurrentSequence());
 
@@ -230,7 +234,7 @@
     // call will return since startPendingPrint will make it return immediately
     // in case of error.
     if (tab)
-      tab->SetPendingPrint();
+      tab->SetPendingPrint(render_process_id_, render_frame_id_);
   }
 #endif
 
diff --git a/chrome/browser/printing/print_job_worker.h b/chrome/browser/printing/print_job_worker.h
index e001a86..f11ae6b 100644
--- a/chrome/browser/printing/print_job_worker.h
+++ b/chrome/browser/printing/print_job_worker.h
@@ -137,6 +137,8 @@
   // The printed document. Only has read-only access.
   scoped_refptr<PrintedDocument> document_;
 
+  int render_process_id_;
+  int render_frame_id_;
   // The print job owning this worker thread. It is guaranteed to outlive this
   // object.
   PrintJobWorkerOwner* owner_;
diff --git a/chrome/browser/profiling_host/DEPS b/chrome/browser/profiling_host/DEPS
new file mode 100644
index 0000000..61ef5fec
--- /dev/null
+++ b/chrome/browser/profiling_host/DEPS
@@ -0,0 +1,3 @@
+include_rules = [
+  "+mojo/edk/embedder",
+]
diff --git a/chrome/browser/profiling_host/profiling_process_host.cc b/chrome/browser/profiling_host/profiling_process_host.cc
index 44626e8a..fafcf47 100644
--- a/chrome/browser/profiling_host/profiling_process_host.cc
+++ b/chrome/browser/profiling_host/profiling_process_host.cc
@@ -8,9 +8,14 @@
 #include "base/path_service.h"
 #include "base/process/launch.h"
 #include "base/strings/string_number_conversions.h"
+#include "build/build_config.h"
 #include "chrome/common/chrome_switches.h"
 #include "chrome/common/profiling/memlog_sender.h"
+#include "chrome/common/profiling/profiling_constants.h"
+#include "content/public/browser/browser_thread.h"
 #include "content/public/common/content_switches.h"
+#include "mojo/edk/embedder/outgoing_broker_client_invitation.h"
+#include "mojo/edk/embedder/platform_channel_pair.h"
 
 #if defined(OS_LINUX)
 #include <fcntl.h>
@@ -68,6 +73,7 @@
 
 ProfilingProcessHost::ProfilingProcessHost() {
   pph_singleton = this;
+  Launch();
 }
 
 ProfilingProcessHost::~ProfilingProcessHost() {
@@ -77,8 +83,6 @@
 // static
 ProfilingProcessHost* ProfilingProcessHost::EnsureStarted() {
   static ProfilingProcessHost host;
-  if (!host.process_.IsValid())
-    host.Launch();
   return &host;
 }
 
@@ -90,52 +94,95 @@
 // static
 void ProfilingProcessHost::AddSwitchesToChildCmdLine(
     base::CommandLine* child_cmd_line) {
+  // Watch out: will be called on different threads.
   ProfilingProcessHost* pph = ProfilingProcessHost::Get();
   if (!pph)
     return;
+  pph->EnsureControlChannelExists();
+
+  // TODO(brettw) this isn't correct for Posix. Redo when we can shave over
+  // Mojo
   child_cmd_line->AppendSwitchASCII(switches::kMemlogPipe, pph->pipe_id_);
 }
 
+void ProfilingProcessHost::Launch() {
+  mojo::edk::PlatformChannelPair control_channel;
+  mojo::edk::HandlePassingInformation handle_passing_info;
+
+// TODO(brettw) most of this logic can be replaced with PlatformChannelPair.
+
 #if defined(OS_WIN)
-void ProfilingProcessHost::Launch() {
   base::Process process = base::Process::Current();
-  base::LaunchOptions options;
-
   pipe_id_ = base::IntToString(static_cast<int>(process.Pid()));
-  base::CommandLine profiling_cmd = MakeProfilingCommandLine(pipe_id_);
+#else
 
-  process_ = base::LaunchProcess(profiling_cmd, options);
-  StartMemlogSender(pipe_id_);
-}
-#elif defined(OS_POSIX)
-
-void ProfilingProcessHost::Launch() {
-  // Create the socketpair.
+  // Create the socketpair for the low level memlog pipe.
   // TODO(ajwong): Should this use base/posix/unix_domain_socket_linux.h?
-  int fds[2];
-  PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0);
-  PCHECK(fcntl(fds[0], F_SETFL, O_NONBLOCK) == 0);
-  PCHECK(fcntl(fds[1], F_SETFL, O_NONBLOCK) == 0);
+  int memlog_fds[2];
+  PCHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, memlog_fds) == 0);
+  PCHECK(fcntl(memlog_fds[0], F_SETFL, O_NONBLOCK) == 0);
+  PCHECK(fcntl(memlog_fds[1], F_SETFL, O_NONBLOCK) == 0);
 
   // Store one end for our message sender to use.
-  pipe_id_ = base::IntToString(fds[0]);
-  base::ScopedFD child_end(fds[1]);
+  base::ScopedFD child_end(memlog_fds[1]);
+  // TODO(brettw) need to get rid of pipe_id when we can share over Mojo.
+  pipe_id_ = base::IntToString(memlog_fds[0]);
 
-  // This is a new process forked from us. No need to remap.
-  base::FileHandleMappingVector fd_map;
-  fd_map.emplace_back(std::pair<int, int>(child_end.get(), child_end.get()));
-
-  base::LaunchOptions options;
-  options.fds_to_remap = &fd_map;
-  options.kill_on_parent_death = true;
-
+  handle_passing_info.emplace_back(child_end.get(), child_end.get());
+#endif
   base::CommandLine profiling_cmd =
       MakeProfilingCommandLine(base::IntToString(child_end.get()));
-  process_ = base::LaunchProcess(profiling_cmd, options);
-  StartMemlogSender(pipe_id_);
-}
+
+  // Keep the server handle, pass the client handle to the child.
+  pending_control_connection_ = control_channel.PassServerHandle();
+  control_channel.PrepareToPassClientHandleToChildProcess(&profiling_cmd,
+                                                          &handle_passing_info);
+
+  base::LaunchOptions options;
+#if defined(OS_WIN)
+  options.handles_to_inherit = &handle_passing_info;
+#elif defined(OS_POSIX)
+  options.fds_to_remap = &handle_passing_info;
+  options.kill_on_parent_death = true;
 #else
 #error Unsupported OS.
 #endif
 
+  process_ = base::LaunchProcess(profiling_cmd, options);
+  StartMemlogSender(pipe_id_);
+}
+
+void ProfilingProcessHost::EnsureControlChannelExists() {
+  // May get called on different threads, we need to be on the IO thread to
+  // work.
+  if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
+    content::BrowserThread::GetTaskRunnerForThread(content::BrowserThread::IO)
+        ->PostTask(
+            FROM_HERE,
+            base::BindOnce(&ProfilingProcessHost::EnsureControlChannelExists,
+                           base::Unretained(this)));
+    return;
+  }
+
+  if (pending_control_connection_.is_valid())
+    ConnectControlChannelOnIO();
+}
+
+// This must be called before the client attempts to connect to the control
+// pipe.
+void ProfilingProcessHost::ConnectControlChannelOnIO() {
+  mojo::edk::OutgoingBrokerClientInvitation invitation;
+  mojo::ScopedMessagePipeHandle control_pipe =
+      invitation.AttachMessagePipe(kProfilingControlPipeName);
+
+  invitation.Send(
+      process_.Handle(),
+      mojo::edk::ConnectionParams(mojo::edk::TransportProtocol::kLegacy,
+                                  std::move(pending_control_connection_)));
+  profiling_control_.Bind(
+      mojom::ProfilingControlPtrInfo(std::move(control_pipe), 0));
+
+  StartProfilingMojo();
+}
+
 }  // namespace profiling
diff --git a/chrome/browser/profiling_host/profiling_process_host.h b/chrome/browser/profiling_host/profiling_process_host.h
index 9023dfe..46eeebd 100644
--- a/chrome/browser/profiling_host/profiling_process_host.h
+++ b/chrome/browser/profiling_host/profiling_process_host.h
@@ -7,6 +7,15 @@
 
 #include "base/macros.h"
 #include "base/process/process.h"
+#include "chrome/common/chrome_features.h"
+#include "chrome/common/profiling/profiling_control.mojom.h"
+#include "mojo/edk/embedder/scoped_platform_handle.h"
+
+// The .mojom include above may not be generated unless OOP heap profiling is
+// enabled.
+#if !BUILDFLAG(ENABLE_OOP_HEAP_PROFILING)
+#error profiling_process_host.h should only be included with OOP heap profiling
+#endif
 
 namespace base {
 class CommandLine;
@@ -48,10 +57,25 @@
 
   void Launch();
 
+  void EnsureControlChannelExists();
+  void ConnectControlChannelOnIO();
+
   // Use process_.IsValid() to determine if the child process has been launched.
   base::Process process_;
   std::string pipe_id_;
 
+  // IO thread only -----------------------------------------------------------
+  //
+  // Once the constructor is finished, the following variables must only be
+  // accessed on the IO thread.
+
+  // Holds the pending server handle for the Mojo control channel during
+  // the period between the profiling process launching and the Mojo channel
+  // being created. Will be invalid otherwise.
+  mojo::edk::ScopedPlatformHandle pending_control_connection_;
+
+  mojom::ProfilingControlPtr profiling_control_;
+
   DISALLOW_COPY_AND_ASSIGN(ProfilingProcessHost);
 };
 
diff --git a/chrome/browser/resources/md_extensions/code_section.html b/chrome/browser/resources/md_extensions/code_section.html
index 88d32c6..c8056e3 100644
--- a/chrome/browser/resources/md_extensions/code_section.html
+++ b/chrome/browser/resources/md_extensions/code_section.html
@@ -1,14 +1,11 @@
+<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
 <link rel="import" href="chrome://resources/html/cr.html">
 <link rel="import" href="chrome://resources/html/polymer.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
 
 <dom-module id="extensions-code-section">
   <template>
-    <style>
-      [hidden] {
-        display: none !important;
-      }
-
+    <style include="cr-hidden-style">
       #main {
         border: 1px solid var(--paper-grey-500);
         color: var(--paper-grey-800);
diff --git a/chrome/browser/resources/md_extensions/detail_view.html b/chrome/browser/resources/md_extensions/detail_view.html
index 5c9c12f..4424074 100644
--- a/chrome/browser/resources/md_extensions/detail_view.html
+++ b/chrome/browser/resources/md_extensions/detail_view.html
@@ -1,3 +1,4 @@
+<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
 <link rel="import" href="chrome://resources/html/cr.html">
 <link rel="import" href="chrome://resources/html/i18n_behavior.html">
 <link rel="import" href="chrome://resources/html/polymer.html">
@@ -12,11 +13,7 @@
 
 <dom-module id="extensions-detail-view">
   <template>
-    <style include="iron-flex">
-      [hidden] {
-        display: none !important;
-      }
-
+    <style include="iron-flex cr-hidden-style">
       :host {
         display: flex;
         justify-content: center;
diff --git a/chrome/browser/resources/md_extensions/drop_overlay.html b/chrome/browser/resources/md_extensions/drop_overlay.html
index f1ae416..ea2646c 100644
--- a/chrome/browser/resources/md_extensions/drop_overlay.html
+++ b/chrome/browser/resources/md_extensions/drop_overlay.html
@@ -1,3 +1,4 @@
+<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
 <link rel="import" href="chrome://resources/html/cr.html">
 <link rel="import" href="chrome://resources/html/cr/ui/drag_wrapper.html">
 <link rel="import" href="chrome://resources/html/load_time_data.html">
@@ -8,11 +9,7 @@
 
 <dom-module id="extensions-drop-overlay">
   <template>
-    <style>
-      [hidden] {
-        display: none !important;
-      }
-
+    <style include="cr-hidden-style">
       :host {
         align-items: center;
         background-color: white;
diff --git a/chrome/browser/resources/md_extensions/error_page.html b/chrome/browser/resources/md_extensions/error_page.html
index 10bcd50..742a824 100644
--- a/chrome/browser/resources/md_extensions/error_page.html
+++ b/chrome/browser/resources/md_extensions/error_page.html
@@ -1,3 +1,4 @@
+<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
 <link rel="import" href="chrome://resources/html/cr.html">
 <link rel="import" href="chrome://resources/html/polymer.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-icons/iron-icons.html">
@@ -10,11 +11,7 @@
 
 <dom-module id="extensions-error-page">
   <template>
-    <style>
-      [hidden] {
-        display: none !important;
-      }
-
+    <style include="cr-hidden-style">
       #main {
         background-color: white;
         height: 800px;
diff --git a/chrome/browser/resources/md_extensions/item.html b/chrome/browser/resources/md_extensions/item.html
index 11c5649..7c5e1c6 100644
--- a/chrome/browser/resources/md_extensions/item.html
+++ b/chrome/browser/resources/md_extensions/item.html
@@ -1,3 +1,4 @@
+<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
 <link rel="import" href="chrome://resources/html/assert.html">
 <link rel="import" href="chrome://resources/html/cr.html">
 <link rel="import" href="chrome://resources/html/i18n_behavior.html">
@@ -15,11 +16,7 @@
 
 <dom-module id="extensions-item">
   <template>
-    <style include="iron-flex">
-      [hidden] {
-        display: none !important;
-      }
-
+    <style include="iron-flex cr-hidden-style">
       #icon-wrapper {
         align-self: flex-start;
         display: flex;
diff --git a/chrome/browser/resources/md_extensions/item_list.html b/chrome/browser/resources/md_extensions/item_list.html
index e4ad4ab..1488373 100644
--- a/chrome/browser/resources/md_extensions/item_list.html
+++ b/chrome/browser/resources/md_extensions/item_list.html
@@ -1,3 +1,4 @@
+<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
 <link rel="import" href="chrome://resources/html/cr.html">
 <link rel="import" href="chrome://resources/html/polymer.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-list/iron-list.html">
@@ -8,7 +9,7 @@
 
 <dom-module id="extensions-item-list">
   <template>
-    <style>
+    <style include="cr-hidden-style">
       :host {
         @apply(--layout-vertical);
       }
@@ -18,11 +19,29 @@
         margin-top: 18px;
       }
 
+      .empty-list-message {
+        align-items: center;
+        color: #6e6e6e;
+        display: flex;
+        flex: 1;
+        font-weight: 500;
+        justify-content: center;
+      }
+
       .wrapper {
         padding: 6px;
       }
     </style>
-    <iron-list id="list" items="[[computeShownItems_(items.*, filter)]]"
+    <div id="no-items" class="empty-list-message"
+        hidden$="[[!shouldShowEmptyItemsMessage_(items.length)]]">
+      <span>$i18nRaw{noExtensionsOrApps}</span>
+    </div>
+    <div id="no-search-results" class="empty-list-message"
+        hidden$="[[!shouldShowEmptySearchMessage_(shownItems_.length)]]">
+      <span>$i18n{noSearchResults}</span>
+    </div>
+
+    <iron-list id="list" items="[[shownItems_]]"
         as="item" grid>
       <template>
         <div class="wrapper">
diff --git a/chrome/browser/resources/md_extensions/item_list.js b/chrome/browser/resources/md_extensions/item_list.js
index 109feeb3..a545b82e 100644
--- a/chrome/browser/resources/md_extensions/item_list.js
+++ b/chrome/browser/resources/md_extensions/item_list.js
@@ -21,6 +21,12 @@
       },
 
       filter: String,
+
+      /** @private {Array<!chrome.developerPrivate.ExtensionInfo>} */
+      shownItems_: {
+        type: Array,
+        computed: 'computeShownItems_(items.*, filter)',
+      }
     },
 
     listeners: {
@@ -73,6 +79,15 @@
         return item.name.toLowerCase().includes(this.filter.toLowerCase());
       }, this);
     },
+
+    shouldShowEmptyItemsMessage_: function() {
+      return this.items.length === 0;
+    },
+
+    shouldShowEmptySearchMessage_: function() {
+      return !this.shouldShowEmptyItemsMessage_() &&
+          this.shownItems_.length === 0;
+    },
   });
 
   return {
diff --git a/chrome/browser/resources/md_extensions/keyboard_shortcuts.html b/chrome/browser/resources/md_extensions/keyboard_shortcuts.html
index 6bf9f203..347e9a0d 100644
--- a/chrome/browser/resources/md_extensions/keyboard_shortcuts.html
+++ b/chrome/browser/resources/md_extensions/keyboard_shortcuts.html
@@ -1,3 +1,4 @@
+<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
 <link rel="import" href="chrome://resources/html/cr.html">
 <link rel="import" href="chrome://resources/html/md_select_css.html">
 <link rel="import" href="chrome://resources/html/polymer.html">
@@ -9,11 +10,7 @@
 
 <dom-module id="extensions-keyboard-shortcuts">
   <template>
-    <style include="md-select">
-      [hidden] {
-        display: none !important;
-      }
-
+    <style include="md-select cr-hidden-style">
       .shortcut-card {
         @apply(--shadow-elevation-2dp);
         background-color: white;
diff --git a/chrome/browser/resources/md_extensions/manager.html b/chrome/browser/resources/md_extensions/manager.html
index c40b130..dfa7722 100644
--- a/chrome/browser/resources/md_extensions/manager.html
+++ b/chrome/browser/resources/md_extensions/manager.html
@@ -1,5 +1,6 @@
 <link rel="import" href="chrome://resources/cr_elements/cr_drawer/cr_drawer.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html">
+<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
 <link rel="import" href="chrome://resources/html/cr.html">
 <link rel="import" href="chrome://resources/html/i18n_behavior.html">
 <link rel="import" href="chrome://resources/html/polymer.html">
@@ -24,11 +25,7 @@
 
 <dom-module id="extensions-manager">
   <template>
-    <style>
-      [hidden] {
-        display: none !important;
-      }
-
+    <style include="cr-hidden-style">
       :host {
         height: 100%;
       }
@@ -89,8 +86,7 @@
           selected="items-list">
         <extensions-item-list id="items-list" items="[[extensions]]"
             delegate="[[itemDelegate]]" in-dev-mode="[[inDevMode]]"
-            filter="[[filter]]"
-            hidden$="[[computeListHidden_(extensions, extensions.splices, apps, apps.splices)]]">
+            filter="[[filter]]" hidden$="[[!didInitPage_]]">
         </extensions-item-list>
         <extensions-detail-view id="details-view" delegate="[[itemDelegate]]"
             in-dev-mode="[[inDevMode]]" data="[[detailViewItem_]]"
diff --git a/chrome/browser/resources/md_extensions/manager.js b/chrome/browser/resources/md_extensions/manager.js
index 4bac6d83..f35cad7 100644
--- a/chrome/browser/resources/md_extensions/manager.js
+++ b/chrome/browser/resources/md_extensions/manager.js
@@ -98,6 +98,15 @@
           return [];
         },
       },
+
+      /**
+       * Prevents page content from showing before data is first loaded.
+       * @private
+       */
+      didInitPage_: {
+        type: Boolean,
+        value: false,
+      },
     },
 
     listeners: {
@@ -171,6 +180,7 @@
      * the user visits chrome://extensions/?id=..., we land on the proper page.
      */
     initPage: function() {
+      this.didInitPage_ = true;
       this.changePage(this.navigationHelper_.getCurrentPage(), true);
     },
 
@@ -236,14 +246,6 @@
     },
 
     /**
-     * @return {boolean} Whether the list should be visible.
-     * @private
-     */
-    computeListHidden_: function() {
-      return this.$['items-list'].items.length == 0;
-    },
-
-    /**
      * Creates and adds a new extensions-item element to the list, inserting it
      * into its sorted position in the relevant section.
      * @param {!chrome.developerPrivate.ExtensionInfo} item The extension
diff --git a/chrome/browser/resources/md_extensions/shortcut_input.html b/chrome/browser/resources/md_extensions/shortcut_input.html
index 64fdc2c..44a916d8 100644
--- a/chrome/browser/resources/md_extensions/shortcut_input.html
+++ b/chrome/browser/resources/md_extensions/shortcut_input.html
@@ -1,3 +1,4 @@
+<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
 <link rel="import" href="chrome://resources/html/assert.html">
 <link rel="import" href="chrome://resources/html/cr.html">
 <link rel="import" href="chrome://resources/html/i18n_behavior.html">
@@ -8,11 +9,7 @@
 
 <dom-module id="extensions-shortcut-input">
   <template>
-    <style>
-      [hidden] {
-        display: none !important;
-      }
-
+    <style include="cr-hidden-style">
       #main {
         position: relative;
         width: 200px;
diff --git a/chrome/browser/resources/md_extensions/toolbar.html b/chrome/browser/resources/md_extensions/toolbar.html
index d496c9b1..faa032e 100644
--- a/chrome/browser/resources/md_extensions/toolbar.html
+++ b/chrome/browser/resources/md_extensions/toolbar.html
@@ -1,3 +1,4 @@
+<link rel="import" href="chrome://resources/cr_elements/hidden_style_css.html">
 <link rel="import" href="chrome://resources/html/cr.html">
 <link rel="import" href="chrome://resources/html/polymer.html">
 <link rel="import" href="chrome://resources/cr_elements/cr_toolbar/cr_toolbar.html">
@@ -8,16 +9,12 @@
 
 <dom-module id="extensions-toolbar">
   <template>
-    <style>
+    <style include="cr-hidden-style">
       :host {
         --toolbar-width: 580px;
         --toolbar-color: var(--md-toolbar-color);
       }
 
-      [hidden] {
-        display: none !important;
-      }
-
       cr-toolbar {
         --cr-toolbar-field-width: var(--toolbar-width);
         background: var(--toolbar-color);
diff --git a/chrome/browser/resources/options/browser_options.html b/chrome/browser/resources/options/browser_options.html
index 94147eac..3d2ce964 100644
--- a/chrome/browser/resources/options/browser_options.html
+++ b/chrome/browser/resources/options/browser_options.html
@@ -615,15 +615,6 @@
         <a target="_blank" href="$i18nRaw{easyUnlockLearnMoreURL}">
           $i18n{learnMore}
         </a>
-        <div id="easy-unlock-enable-proximity-detection" class="checkbox"
-            hidden>
-          <label>
-            <input type="checkbox"
-                metric="Options_EasyUnlockRequireProximity"
-                pref="easy_unlock.proximity_required">
-            <span>$i18n{easyUnlockRequireProximityLabel}</span>
-          </label>
-        </div>
       </div>
       <button id="easy-unlock-turn-off-button">
         $i18n{easyUnlockTurnOffButton}
diff --git a/chrome/browser/resources/options/browser_options.js b/chrome/browser/resources/options/browser_options.js
index 2266bdbe..a407bf63 100644
--- a/chrome/browser/resources/options/browser_options.js
+++ b/chrome/browser/resources/options/browser_options.js
@@ -661,8 +661,6 @@
           PageManager.showPageByName('easyUnlockTurnOffOverlay');
         };
       }
-      $('easy-unlock-enable-proximity-detection').hidden =
-          !loadTimeData.getBoolean('easyUnlockProximityDetectionAllowed');
 
       // Web Content section.
       $('fontSettingsCustomizeFontsButton').onclick = function(event) {
diff --git a/chrome/browser/resources/print_preview/print_preview.js b/chrome/browser/resources/print_preview/print_preview.js
index cb37122f..cb052c9d 100644
--- a/chrome/browser/resources/print_preview/print_preview.js
+++ b/chrome/browser/resources/print_preview/print_preview.js
@@ -574,8 +574,18 @@
           this.documentInfo_,
           this.uiState_ == PrintPreviewUiState_.OPENING_PDF_PREVIEW,
           this.showSystemDialogBeforeNextPrint_);
-
-      if (!destination.isLocal) {
+      if (this.uiState_ == PrintPreviewUiState_.OPENING_PDF_PREVIEW ||
+          (destination.isLocal && !destination.isPrivet &&
+           !destination.isExtension &&
+           destination.id !=
+               print_preview.Destination.GooglePromotedId.SAVE_AS_PDF)) {
+        // Local printers resolve when print is ready to start. Hide the
+        // dialog. Mac "Open in Preview" is treated as a local printer.
+        var boundHideDialog = function() {
+          this.nativeLayer_.startHideDialog();
+        }.bind(this);
+        whenPrintDone.then(boundHideDialog, boundHideDialog);
+      } else if (!destination.isLocal) {
         // Cloud print resolves when print data is returned to submit to cloud
         // print, or if setings are invalid.
         whenPrintDone.then(
@@ -587,20 +597,14 @@
         whenPrintDone.then(
             this.close_.bind(this, false),
             this.onPrintFailed_.bind(this));
-      } else if (
-          destination.id ==
-          print_preview.Destination.GooglePromotedId.SAVE_AS_PDF) {
+      } else {
+        assert(
+            destination.id ==
+            print_preview.Destination.GooglePromotedId.SAVE_AS_PDF);
         // Save as PDF resolves when file selection is completed or cancelled.
         whenPrintDone.then(
             this.onFileSelectionComplete_.bind(this),
             this.onFileSelectionCancel_.bind(this));
-      } else {  // standard local printer
-        var boundHideDialog = function () {
-          this.nativeLayer_.startHideDialog();
-        }.bind(this);
-        // Local printers resolve when print is ready to start. Hide the
-        // dialog.
-        whenPrintDone.then(boundHideDialog, boundHideDialog);
       }
 
       this.showSystemDialogBeforeNextPrint_ = false;
diff --git a/chrome/browser/resources/settings/people_page/lock_screen.html b/chrome/browser/resources/settings/people_page/lock_screen.html
index e2b8b7d6..677ad20 100644
--- a/chrome/browser/resources/settings/people_page/lock_screen.html
+++ b/chrome/browser/resources/settings/people_page/lock_screen.html
@@ -135,13 +135,6 @@
               <a target="_blank" href="$i18n{easyUnlockLearnMoreURL}">
                 $i18n{learnMore}
               </a>
-              <template is="dom-if" if="[[getShowEasyUnlockToggle_(
-                  easyUnlockEnabled_, easyUnlockProximityDetectionAllowed_)]]">
-                <settings-toggle-button
-                    pref="{{prefs.easy_unlock.proximity_required}}"
-                    label="$i18n{easyUnlockRequireProximityLabel}">
-                </settings-toggle-button>
-              </template>
             </div>
           </div>
           <div class="separator"></div>
diff --git a/chrome/browser/resources/settings/people_page/lock_screen.js b/chrome/browser/resources/settings/people_page/lock_screen.js
index 4e14d4b..520669c 100644
--- a/chrome/browser/resources/settings/people_page/lock_screen.js
+++ b/chrome/browser/resources/settings/people_page/lock_screen.js
@@ -106,18 +106,6 @@
       },
     },
 
-    /**
-     * True if Easy Unlock's proximity detection feature is allowed.
-     */
-    easyUnlockProximityDetectionAllowed_: {
-      type: Boolean,
-      value: function() {
-        return loadTimeData.getBoolean('easyUnlockAllowed') &&
-            loadTimeData.getBoolean('easyUnlockProximityDetectionAllowed');
-      },
-      readOnly: true,
-    },
-
     /** @private */
     showEasyUnlockTurnOffDialog_: {
       type: Boolean,
diff --git a/chrome/browser/safe_browsing/BUILD.gn b/chrome/browser/safe_browsing/BUILD.gn
index 457a58a1..d5dc53b 100644
--- a/chrome/browser/safe_browsing/BUILD.gn
+++ b/chrome/browser/safe_browsing/BUILD.gn
@@ -19,6 +19,8 @@
     "chrome_cleaner/chrome_cleaner_controller_win.h",
     "chrome_cleaner/chrome_cleaner_fetcher_win.cc",
     "chrome_cleaner/chrome_cleaner_fetcher_win.h",
+    "chrome_cleaner/chrome_cleaner_navigation_util_win.cc",
+    "chrome_cleaner/chrome_cleaner_navigation_util_win.h",
     "chrome_cleaner/chrome_cleaner_runner_win.cc",
     "chrome_cleaner/chrome_cleaner_runner_win.h",
     "chrome_cleaner/reporter_runner_win.cc",
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.cc
index cb9d883..b0f2d24 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.cc
+++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_controller_win.cc
@@ -25,15 +25,18 @@
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_fetcher_win.h"
+#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_navigation_util_win.h"
 #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_runner_win.h"
 #include "chrome/browser/safe_browsing/chrome_cleaner/settings_resetter_win.h"
 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_client_info_win.h"
 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h"
+#include "chrome/browser/ui/browser.h"
 #include "chrome/installer/util/scoped_token_privilege.h"
 #include "components/chrome_cleaner/public/constants/constants.h"
 #include "components/safe_browsing/common/safe_browsing_prefs.h"
 #include "content/public/browser/browser_thread.h"
 #include "net/http/http_status_code.h"
+#include "ui/base/window_open_disposition.h"
 
 namespace safe_browsing {
 
@@ -511,6 +514,12 @@
     if (process_status.exit_code == kRebootRequiredExitCode) {
       RecordCleanupResultHistogram(CLEANUP_RESULT_REBOOT_REQUIRED);
       SetStateAndNotifyObservers(State::kRebootRequired);
+
+      Browser* browser = chrome_cleaner_util::FindBrowser();
+      if (browser)
+        chrome_cleaner_util::OpenSettingsPage(
+            browser, WindowOpenDisposition::NEW_BACKGROUND_TAB,
+            /*skip_if_current_tab=*/true);
       return;
     }
 
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.cc
index 72b58371..cfaa7435 100644
--- a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.cc
+++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.cc
@@ -5,41 +5,20 @@
 #include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_dialog_controller_impl_win.h"
 
 #include "base/metrics/histogram_macros.h"
+#include "chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_navigation_util_win.h"
 #include "chrome/browser/safe_browsing/chrome_cleaner/srt_field_trial_win.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_dialogs.h"
-#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/browser_list.h"
-#include "chrome/browser/ui/browser_window.h"
-#include "chrome/common/url_constants.h"
-#include "content/public/browser/page_navigator.h"
-#include "ui/base/page_transition_types.h"
 #include "ui/base/window_open_disposition.h"
-#include "url/gurl.h"
 
 namespace safe_browsing {
 
 namespace {
 
 void OpenSettingsPage(Browser* browser) {
-  browser->OpenURL(content::OpenURLParams(
-      GURL(chrome::kChromeUISettingsURL), content::Referrer(),
-      WindowOpenDisposition::NEW_FOREGROUND_TAB,
-      ui::PAGE_TRANSITION_AUTO_TOPLEVEL, /*is_renderer_initiated=*/false));
-}
-
-Browser* FindBrowserForDialog() {
-  BrowserList* browser_list = BrowserList::GetInstance();
-  for (BrowserList::const_reverse_iterator browser_iterator =
-           browser_list->begin_last_active();
-       browser_iterator != browser_list->end_last_active();
-       ++browser_iterator) {
-    Browser* browser = *browser_iterator;
-    if (browser->window()->IsActive() || !browser->window()->IsMinimized())
-      return browser;
-  }
-
-  return nullptr;
+  chrome_cleaner_util::OpenSettingsPage(
+      browser, WindowOpenDisposition::NEW_FOREGROUND_TAB,
+      /*skip_if_current_tab=*/false);
 }
 
 // These values are used to send UMA information and are replicated in the
@@ -147,7 +126,7 @@
     const std::set<base::FilePath>& files_to_delete) {
   DCHECK(!dialog_shown_);
 
-  browser_ = FindBrowserForDialog();
+  browser_ = chrome_cleaner_util::FindBrowser();
   if (!browser_) {
     // TODO(alito): Register with chrome::BrowserListObserver to get notified
     // later if a suitable browser window becomes available to show the
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_navigation_util_win.cc b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_navigation_util_win.cc
new file mode 100644
index 0000000..7534df8
--- /dev/null
+++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_navigation_util_win.cc
@@ -0,0 +1,50 @@
+// 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/safe_browsing/chrome_cleaner/chrome_cleaner_navigation_util_win.h"
+
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/url_constants.h"
+#include "ui/base/page_transition_types.h"
+#include "ui/base/window_open_disposition.h"
+#include "url/gurl.h"
+
+namespace chrome_cleaner_util {
+
+Browser* FindBrowser() {
+  BrowserList* browser_list = BrowserList::GetInstance();
+  for (BrowserList::const_reverse_iterator browser_iterator =
+           browser_list->begin_last_active();
+       browser_iterator != browser_list->end_last_active();
+       ++browser_iterator) {
+    Browser* browser = *browser_iterator;
+    if (browser->is_type_tabbed() &&
+        (browser->window()->IsActive() || !browser->window()->IsMinimized()))
+      return browser;
+  }
+
+  return nullptr;
+}
+
+void OpenSettingsPage(Browser* browser,
+                      WindowOpenDisposition disposition,
+                      bool skip_if_current_tab) {
+  DCHECK(browser);
+
+  // Skip opening the settings page if it's already the currently active tab.
+  content::WebContents* web_contents =
+      browser->tab_strip_model()->GetActiveWebContents();
+  if (skip_if_current_tab && web_contents &&
+      web_contents->GetLastCommittedURL() == chrome::kChromeUISettingsURL) {
+    return;
+  }
+
+  browser->OpenURL(content::OpenURLParams(
+      GURL(chrome::kChromeUISettingsURL), content::Referrer(), disposition,
+      ui::PAGE_TRANSITION_AUTO_TOPLEVEL, /*is_renderer_initiated=*/false));
+}
+
+}  // namespace chrome_cleaner_util
diff --git a/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_navigation_util_win.h b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_navigation_util_win.h
new file mode 100644
index 0000000..7677002f
--- /dev/null
+++ b/chrome/browser/safe_browsing/chrome_cleaner/chrome_cleaner_navigation_util_win.h
@@ -0,0 +1,25 @@
+// 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_SAFE_BROWSING_CHROME_CLEANER_CHROME_CLEANER_NAVIGATION_UTIL_WIN_H_
+#define CHROME_BROWSER_SAFE_BROWSING_CHROME_CLEANER_CHROME_CLEANER_NAVIGATION_UTIL_WIN_H_
+
+#include "chrome/browser/ui/browser.h"
+
+namespace chrome_cleaner_util {
+
+// Returns the last active tabbed browser or NULL if no such browser currently
+// exists.
+Browser* FindBrowser();
+
+// Opens a new settings tab in |browser| with the given |disposition|.
+// If |skip_if_current_tab| is true and settings is the currently displayed
+// tab, no new tab is opened.
+void OpenSettingsPage(Browser* browser,
+                      WindowOpenDisposition disposition,
+                      bool skip_if_current_tab);
+
+}  // namespace chrome_cleaner_util
+
+#endif  // CHROME_BROWSER_SAFE_BROWSING_CHROME_CLEANER_CHROME_CLEANER_NAVIGATION_UTIL_WIN_H_
diff --git a/chrome/browser/signin/easy_unlock_service.cc b/chrome/browser/signin/easy_unlock_service.cc
index 985c044..fc9b3ff 100644
--- a/chrome/browser/signin/easy_unlock_service.cc
+++ b/chrome/browser/signin/easy_unlock_service.cc
@@ -75,13 +75,6 @@
 
 }  // namespace
 
-EasyUnlockService::UserSettings::UserSettings()
-    : require_close_proximity(false) {
-}
-
-EasyUnlockService::UserSettings::~UserSettings() {
-}
-
 // static
 EasyUnlockService* EasyUnlockService::Get(Profile* profile) {
   return EasyUnlockServiceFactory::GetForBrowserContext(profile);
@@ -259,10 +252,6 @@
   registry->RegisterBooleanPref(prefs::kEasyUnlockEnabled, false);
   registry->RegisterDictionaryPref(prefs::kEasyUnlockPairing,
                                    base::MakeUnique<base::DictionaryValue>());
-  registry->RegisterBooleanPref(
-      prefs::kEasyUnlockProximityRequired,
-      false,
-      user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
 
   if (base::CommandLine::ForCurrentProcess()->HasSwitch(
           proximity_auth::switches::kEnableBluetoothLowEnergyDiscovery))
@@ -296,33 +285,6 @@
 }
 
 // static
-EasyUnlockService::UserSettings EasyUnlockService::GetUserSettings(
-    const AccountId& account_id) {
-  DCHECK(account_id.is_valid());
-  UserSettings user_settings;
-
-  PrefService* local_state = GetLocalState();
-  if (!local_state)
-    return user_settings;
-
-  const base::DictionaryValue* all_user_prefs_dict =
-      local_state->GetDictionary(prefs::kEasyUnlockLocalStateUserPrefs);
-  if (!all_user_prefs_dict)
-    return user_settings;
-
-  const base::DictionaryValue* user_prefs_dict;
-  if (!all_user_prefs_dict->GetDictionaryWithoutPathExpansion(
-          account_id.GetUserEmail(), &user_prefs_dict))
-    return user_settings;
-
-  user_prefs_dict->GetBooleanWithoutPathExpansion(
-      prefs::kEasyUnlockProximityRequired,
-      &user_settings.require_close_proximity);
-
-  return user_settings;
-}
-
-// static
 std::string EasyUnlockService::GetDeviceId() {
   PrefService* local_state = GetLocalState();
   if (!local_state)
diff --git a/chrome/browser/signin/easy_unlock_service.h b/chrome/browser/signin/easy_unlock_service.h
index 2446d75a..4d61cc8 100644
--- a/chrome/browser/signin/easy_unlock_service.h
+++ b/chrome/browser/signin/easy_unlock_service.h
@@ -63,16 +63,6 @@
     TYPE_SIGNIN
   };
 
-  // Easy Unlock settings that the user can configure.
-  struct UserSettings {
-    UserSettings();
-    ~UserSettings();
-
-    // Whether to require the remote device to be in very close proximity
-    // before allowing unlock (~1 feet).
-    bool require_close_proximity;
-  };
-
   // Gets EasyUnlockService instance.
   static EasyUnlockService* Get(Profile* profile);
 
@@ -89,9 +79,6 @@
   // Removes the hardlock state for the given user.
   static void ResetLocalStateForUser(const AccountId& account_id);
 
-  // Returns the user's preferences.
-  static UserSettings GetUserSettings(const AccountId& account_id);
-
   // Returns the identifier for the device.
   static std::string GetDeviceId();
 
diff --git a/chrome/browser/signin/easy_unlock_service_regular.cc b/chrome/browser/signin/easy_unlock_service_regular.cc
index 0c3dabce..cfb66f2 100644
--- a/chrome/browser/signin/easy_unlock_service_regular.cc
+++ b/chrome/browser/signin/easy_unlock_service_regular.cc
@@ -447,9 +447,6 @@
       prefs::kEasyUnlockAllowed,
       base::Bind(&EasyUnlockServiceRegular::OnPrefsChanged,
                  base::Unretained(this)));
-  registrar_.Add(prefs::kEasyUnlockProximityRequired,
-                 base::Bind(&EasyUnlockServiceRegular::OnPrefsChanged,
-                            base::Unretained(this)));
 
   OnPrefsChanged();
 
@@ -611,9 +608,6 @@
   // items in the dictionary are the same profile prefs used for Easy Unlock.
   std::unique_ptr<base::DictionaryValue> user_prefs_dict(
       new base::DictionaryValue());
-  user_prefs_dict->SetBooleanWithoutPathExpansion(
-      prefs::kEasyUnlockProximityRequired,
-      profile_prefs->GetBoolean(prefs::kEasyUnlockProximityRequired));
 
   DictionaryPrefUpdate update(local_state,
                               prefs::kEasyUnlockLocalStateUserPrefs);
diff --git a/chrome/browser/ssl/cert_report_helper.cc b/chrome/browser/ssl/cert_report_helper.cc
index 418750ad..923ee3d 100644
--- a/chrome/browser/ssl/cert_report_helper.cc
+++ b/chrome/browser/ssl/cert_report_helper.cc
@@ -16,6 +16,7 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ssl/ssl_cert_reporter.h"
+#include "chrome/common/channel_info.h"
 #include "chrome/common/pref_names.h"
 #include "components/prefs/pref_service.h"
 #include "components/safe_browsing/common/safe_browsing_prefs.h"
@@ -125,6 +126,8 @@
 
   report.AddNetworkTimeInfo(g_browser_process->network_time_tracker());
 
+  report.AddChromeChannel(chrome::GetChannel());
+
   report.SetInterstitialInfo(
       interstitial_reason_, user_proceeded,
       overridable_
diff --git a/chrome/browser/ssl/certificate_reporting_test_utils.cc b/chrome/browser/ssl/certificate_reporting_test_utils.cc
index ba04b2bfa6..63e89c1 100644
--- a/chrome/browser/ssl/certificate_reporting_test_utils.cc
+++ b/chrome/browser/ssl/certificate_reporting_test_utils.cc
@@ -32,7 +32,10 @@
 class MockSSLCertReporter : public SSLCertReporter {
  public:
   MockSSLCertReporter(
-      const base::Callback<void(const std::string&)>& report_sent_callback,
+      const base::Callback<
+          void(const std::string&,
+               const certificate_reporting::CertLoggerRequest_ChromeChannel)>&
+          report_sent_callback,
       ExpectReport expect_report)
       : report_sent_callback_(report_sent_callback),
         expect_report_(expect_report),
@@ -52,11 +55,14 @@
     reported_ = true;
     certificate_reporting::ErrorReport report;
     EXPECT_TRUE(report.InitializeFromString(serialized_report));
-    report_sent_callback_.Run(report.hostname());
+    report_sent_callback_.Run(report.hostname(), report.chrome_channel());
   }
 
  private:
-  const base::Callback<void(const std::string&)> report_sent_callback_;
+  const base::Callback<void(
+      const std::string&,
+      const certificate_reporting::CertLoggerRequest_ChromeChannel)>
+      report_sent_callback_;
   const ExpectReport expect_report_;
   bool reported_;
 
@@ -64,12 +70,18 @@
 };
 
 SSLCertReporterCallback::SSLCertReporterCallback(base::RunLoop* run_loop)
-    : run_loop_(run_loop) {}
+    : run_loop_(run_loop),
+      chrome_channel_(
+          certificate_reporting::CertLoggerRequest::CHROME_CHANNEL_NONE) {}
 
 SSLCertReporterCallback::~SSLCertReporterCallback() {}
 
-void SSLCertReporterCallback::ReportSent(const std::string& hostname) {
+void SSLCertReporterCallback::ReportSent(
+    const std::string& hostname,
+    const certificate_reporting::CertLoggerRequest::ChromeChannel
+        chrome_channel) {
   latest_hostname_reported_ = hostname;
+  chrome_channel_ = chrome_channel;
   run_loop_->Quit();
 }
 
@@ -77,13 +89,21 @@
   return latest_hostname_reported_;
 }
 
+certificate_reporting::CertLoggerRequest::ChromeChannel
+SSLCertReporterCallback::GetLatestChromeChannelReported() const {
+  return chrome_channel_;
+}
+
 void SetCertReportingOptIn(Browser* browser, OptIn opt_in) {
   safe_browsing::SetExtendedReportingPref(browser->profile()->GetPrefs(),
                                           opt_in == EXTENDED_REPORTING_OPT_IN);
 }
 
 std::unique_ptr<SSLCertReporter> CreateMockSSLCertReporter(
-    const base::Callback<void(const std::string&)>& report_sent_callback,
+    const base::Callback<
+        void(const std::string&,
+             const certificate_reporting::CertLoggerRequest_ChromeChannel)>&
+        report_sent_callback,
     ExpectReport expect_report) {
   return std::unique_ptr<SSLCertReporter>(
       new MockSSLCertReporter(report_sent_callback, expect_report));
diff --git a/chrome/browser/ssl/certificate_reporting_test_utils.h b/chrome/browser/ssl/certificate_reporting_test_utils.h
index 94d7bdb..6628bdf 100644
--- a/chrome/browser/ssl/certificate_reporting_test_utils.h
+++ b/chrome/browser/ssl/certificate_reporting_test_utils.h
@@ -10,6 +10,7 @@
 
 #include "base/macros.h"
 #include "chrome/browser/ssl/ssl_cert_reporter.h"
+#include "components/certificate_reporting/cert_logger.pb.h"
 #include "components/certificate_reporting/error_reporter.h"
 
 class Browser;
@@ -36,13 +37,18 @@
   explicit SSLCertReporterCallback(base::RunLoop* run_loop);
   ~SSLCertReporterCallback();
 
-  void ReportSent(const std::string& hostname);
+  void ReportSent(const std::string& hostname,
+                  const certificate_reporting::CertLoggerRequest::ChromeChannel
+                      chrome_channel);
 
   const std::string& GetLatestHostnameReported() const;
+  certificate_reporting::CertLoggerRequest::ChromeChannel
+  GetLatestChromeChannelReported() const;
 
  private:
   base::RunLoop* run_loop_;
   std::string latest_hostname_reported_;
+  certificate_reporting::CertLoggerRequest::ChromeChannel chrome_channel_;
 
   DISALLOW_COPY_AND_ASSIGN(SSLCertReporterCallback);
 };
@@ -55,7 +61,10 @@
 // |report_sent_callback| when a report is sent. It also checks that a
 // report is sent or not sent according to |expect_report|.
 std::unique_ptr<SSLCertReporter> CreateMockSSLCertReporter(
-    const base::Callback<void(const std::string&)>& report_sent_callback,
+    const base::Callback<
+        void(const std::string&,
+             const certificate_reporting::CertLoggerRequest_ChromeChannel)>&
+        report_sent_callback,
     ExpectReport expect_report);
 
 // Returns whether a report should be expected (due to the Finch config)
diff --git a/chrome/browser/ssl/chrome_expect_ct_reporter_browser_tests.cc b/chrome/browser/ssl/chrome_expect_ct_reporter_browser_tests.cc
new file mode 100644
index 0000000..a66ea2f
--- /dev/null
+++ b/chrome/browser/ssl/chrome_expect_ct_reporter_browser_tests.cc
@@ -0,0 +1,124 @@
+// 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 "base/bind.h"
+#include "base/callback.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ssl/cert_verifier_browser_test.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "net/cert/mock_cert_verifier.h"
+#include "net/http/transport_security_state.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_request.h"
+#include "net/test/embedded_test_server/http_response.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_getter.h"
+
+namespace {
+
+// A test fixture that allows tests to wait for an Expect-CT report to be
+// received by a server.
+class ExpectCTBrowserTest : public CertVerifierBrowserTest {
+ public:
+  ExpectCTBrowserTest() : CertVerifierBrowserTest() {}
+
+  void SetUpOnMainThread() override {
+    run_loop_ = base::MakeUnique<base::RunLoop>();
+  }
+
+  void TearDown() override { run_loop_.reset(nullptr); }
+
+  std::unique_ptr<net::test_server::HttpResponse> ReportRequestHandler(
+      const net::test_server::HttpRequest& request) {
+    EXPECT_TRUE(request.method == net::test_server::METHOD_POST ||
+                request.method == net::test_server::METHOD_OPTIONS)
+        << "Request method must be POST or OPTIONS. It is " << request.method
+        << ".";
+    std::unique_ptr<net::test_server::BasicHttpResponse> http_response(
+        new net::test_server::BasicHttpResponse());
+    http_response->set_code(net::HTTP_OK);
+
+    // Respond properly to CORS preflights.
+    if (request.method == net::test_server::METHOD_OPTIONS) {
+      http_response->AddCustomHeader("Access-Control-Allow-Origin", "*");
+      http_response->AddCustomHeader("Access-Control-Allow-Methods", "POST");
+      http_response->AddCustomHeader("Access-Control-Allow-Headers",
+                                     "content-type");
+    } else if (request.method == net::test_server::METHOD_POST) {
+      auto it = request.headers.find("Content-Type");
+      EXPECT_NE(it, request.headers.end());
+      // The above EXPECT_NE is really an ASSERT_NE in spirit, but can't ASSERT
+      // because a response must be returned.
+      if (it != request.headers.end()) {
+        EXPECT_EQ("application/expect-ct-report+json; charset=utf-8",
+                  it->second);
+      }
+      run_loop_->QuitClosure().Run();
+    }
+
+    return http_response;
+  }
+
+ protected:
+  void WaitForReport() { run_loop_->Run(); }
+
+ private:
+  std::unique_ptr<base::RunLoop> run_loop_;
+
+  DISALLOW_COPY_AND_ASSIGN(ExpectCTBrowserTest);
+};
+
+void AddExpectCTHeaderOnIO(net::URLRequestContextGetter* getter,
+                           const std::string& host,
+                           const GURL& report_uri) {
+  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+  net::URLRequestContext* context = getter->GetURLRequestContext();
+  context->transport_security_state()->AddExpectCT(
+      host, base::Time::Now() + base::TimeDelta::FromSeconds(1000), true,
+      report_uri);
+}
+
+// Tests that an Expect-CT reporter is properly set up and used for violations
+// of Expect-CT HTTP headers.
+IN_PROC_BROWSER_TEST_F(ExpectCTBrowserTest, TestDynamicExpectCTReporting) {
+  net::EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
+  ASSERT_TRUE(test_server.Start());
+
+  net::EmbeddedTestServer report_server;
+  report_server.RegisterRequestHandler(base::Bind(
+      &ExpectCTBrowserTest::ReportRequestHandler, base::Unretained(this)));
+  ASSERT_TRUE(report_server.Start());
+
+  // Set up the mock cert verifier to accept |test_server|'s certificate as
+  // valid and as if it is issued by a known root. (CT checks are skipped for
+  // private roots.)
+  scoped_refptr<net::X509Certificate> cert(test_server.GetCertificate());
+  net::CertVerifyResult verify_result;
+  verify_result.is_issued_by_known_root = true;
+  verify_result.verified_cert = cert;
+  verify_result.cert_status = 0;
+  mock_cert_verifier()->AddResultForCert(cert, verify_result, net::OK);
+
+  // Fire off a task to simulate as if a previous request to |test_server| had
+  // set a valid Expect-CT header.
+  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
+      browser()->profile()->GetRequestContext();
+  content::BrowserThread::PostTask(
+      content::BrowserThread::IO, FROM_HERE,
+      base::BindOnce(
+          &AddExpectCTHeaderOnIO, base::RetainedRef(url_request_context_getter),
+          test_server.GetURL("/").host(), report_server.GetURL("/")));
+
+  // Navigate to a test server URL, which should trigger an Expect-CT report
+  // because the test server doesn't serve SCTs.
+  ui_test_utils::NavigateToURL(browser(), test_server.GetURL("/"));
+  WaitForReport();
+  // WaitForReport() does not return util ReportRequestHandler runs, and the
+  // handler does all the assertions, so there are no more assertions needed
+  // here.
+}
+
+}  // namespace
diff --git a/chrome/browser/ssl/ssl_browser_tests.cc b/chrome/browser/ssl/ssl_browser_tests.cc
index d2698e0..9b93a337 100644
--- a/chrome/browser/ssl/ssl_browser_tests.cc
+++ b/chrome/browser/ssl/ssl_browser_tests.cc
@@ -609,6 +609,8 @@
         std::move(ssl_cert_reporter));
 
     EXPECT_EQ(std::string(), reporter_callback.GetLatestHostnameReported());
+    EXPECT_EQ(certificate_reporting::CertLoggerRequest::CHROME_CHANNEL_NONE,
+              reporter_callback.GetLatestChromeChannelReported());
 
     // Leave the interstitial (either by proceeding or going back)
     if (proceed == SSL_INTERSTITIAL_PROCEED) {
@@ -626,9 +628,13 @@
       run_loop.Run();
       EXPECT_EQ(https_server_expired_.GetURL("/title1.html").host(),
                 reporter_callback.GetLatestHostnameReported());
+      EXPECT_NE(certificate_reporting::CertLoggerRequest::CHROME_CHANNEL_NONE,
+                reporter_callback.GetLatestChromeChannelReported());
     } else {
       base::RunLoop().RunUntilIdle();
       EXPECT_EQ(std::string(), reporter_callback.GetLatestHostnameReported());
+      EXPECT_EQ(certificate_reporting::CertLoggerRequest::CHROME_CHANNEL_NONE,
+                reporter_callback.GetLatestChromeChannelReported());
     }
   }
 
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
index 4da996d..9f706a00 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.cc
@@ -10,6 +10,7 @@
 
 #include "base/files/file_util.h"
 #include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/task_scheduler/post_task.h"
@@ -17,6 +18,7 @@
 #include "chrome/browser/chromeos/arc/arc_session_manager.h"
 #include "chrome/browser/chromeos/arc/arc_util.h"
 #include "chrome/browser/chromeos/arc/policy/arc_policy_util.h"
+#include "chrome/browser/chromeos/login/session/user_session_manager.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/app_list/app_list_service.h"
 #include "chrome/browser/ui/app_list/arc/arc_app_list_prefs_factory.h"
@@ -617,8 +619,7 @@
   return app_info && app_info->shortcut;
 }
 
-void ArcAppListPrefs::SetLastLaunchTime(const std::string& app_id,
-                                        const base::Time& time) {
+void ArcAppListPrefs::SetLastLaunchTime(const std::string& app_id) {
   if (!IsRegistered(app_id)) {
     NOTREACHED();
     return;
@@ -628,10 +629,29 @@
   if (!arc::ShouldShowInLauncher(app_id))
     return;
 
+  const base::Time time = base::Time::Now();
   ScopedArcPrefUpdate update(prefs_, app_id, prefs::kArcApps);
   base::DictionaryValue* app_dict = update.Get();
   const std::string string_value = base::Int64ToString(time.ToInternalValue());
   app_dict->SetString(kLastLaunchTime, string_value);
+
+  if (first_launch_app_request_) {
+    first_launch_app_request_ = false;
+    // UI Shown time may not be set in unit tests.
+    const user_manager::UserManager* user_manager =
+        user_manager::UserManager::Get();
+    if (arc::ArcSessionManager::Get()->is_directly_started() &&
+        !user_manager->IsLoggedInAsKioskApp() &&
+        !user_manager->IsLoggedInAsArcKioskApp() &&
+        !chromeos::UserSessionManager::GetInstance()
+             ->ui_shown_time()
+             .is_null()) {
+      UMA_HISTOGRAM_CUSTOM_TIMES(
+          "Arc.FirstAppLaunchRequest.TimeDelta",
+          time - chromeos::UserSessionManager::GetInstance()->ui_shown_time(),
+          base::TimeDelta::FromSeconds(1), base::TimeDelta::FromMinutes(2), 20);
+    }
+  }
 }
 
 void ArcAppListPrefs::DisableAllApps() {
@@ -817,7 +837,7 @@
   DCHECK(IsArcAndroidEnabledForProfile(profile_));
   const std::string app_id = GetAppId(package_name, activity);
   if (IsRegistered(app_id)) {
-    SetLastLaunchTime(app_id, base::Time::Now());
+    SetLastLaunchTime(app_id);
   } else {
     // Create runtime app entry that is valid for the current user session. This
     // entry is not shown in App Launcher and only required for shelf
diff --git a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h
index d849fb5c7..05f82cd 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h
+++ b/chrome/browser/ui/app_list/arc/arc_app_list_prefs.h
@@ -205,7 +205,7 @@
       ui::ScaleFactor scale_factor) const;
 
   // Sets last launched time for the requested app.
-  void SetLastLaunchTime(const std::string& app_id, const base::Time& time);
+  void SetLastLaunchTime(const std::string& app_id);
 
   // Calls RequestIcon if no request is recorded.
   void MaybeRequestIcon(const std::string& app_id,
@@ -441,6 +441,8 @@
   bool apps_restored_ = false;
   // True is ARC package list has been successfully refreshed.
   bool package_list_initial_refreshed_ = false;
+  // Used to detect first ARC app launch request.
+  bool first_launch_app_request_ = true;
   // Play Store does not have publicly available observers for default app
   // installations. This timeout is for validating default app availability.
   // Default apps should be either already installed or their installations
diff --git a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
index 8341a60..73221d9 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_unittest.cc
@@ -1081,19 +1081,19 @@
   EXPECT_EQ(base::Time(), app_info->last_launch_time);
 
   // Test direct setting last launch time.
-  const base::Time now_time = base::Time::Now();
-  prefs->SetLastLaunchTime(id1, now_time);
+  const base::Time before_time = base::Time::Now();
+  prefs->SetLastLaunchTime(id1);
 
   app_info = prefs->GetApp(id1);
   ASSERT_NE(nullptr, app_info.get());
-  EXPECT_EQ(now_time, app_info->last_launch_time);
+  EXPECT_GE(app_info->last_launch_time, before_time);
 
   // Test setting last launch time via LaunchApp.
   app_info = prefs->GetApp(id2);
   ASSERT_NE(nullptr, app_info.get());
   EXPECT_EQ(base::Time(), app_info->last_launch_time);
 
-  const base::Time time_before = base::Time::Now();
+  base::Time time_before = base::Time::Now();
   arc::LaunchApp(profile(), id2, ui::EF_NONE);
   const base::Time time_after = base::Time::Now();
 
@@ -1107,10 +1107,11 @@
   app_info = prefs->GetApp(id3);
   ASSERT_NE(nullptr, app_info.get());
   EXPECT_EQ(base::Time(), app_info->last_launch_time);
+  time_before = base::Time::Now();
   app_instance()->SendTaskCreated(0, fake_apps()[2], std::string());
   app_info = prefs->GetApp(id3);
   ASSERT_NE(nullptr, app_info.get());
-  EXPECT_GE(app_info->last_launch_time, now_time);
+  EXPECT_GE(app_info->last_launch_time, time_before);
 }
 
 // Validate that arc model contains expected elements on restart.
@@ -1648,12 +1649,12 @@
   ValidateHaveAppsAndShortcuts(apps1, shortcuts);
 
   const std::string app_id = ArcAppTest::GetAppId(apps[1]);
-  const base::Time now_time = base::Time::Now();
-  prefs->SetLastLaunchTime(app_id, now_time);
+  const base::Time time_before = base::Time::Now();
+  prefs->SetLastLaunchTime(app_id);
   std::unique_ptr<ArcAppListPrefs::AppInfo> app_info_before =
       prefs->GetApp(app_id);
   ASSERT_TRUE(app_info_before);
-  EXPECT_EQ(now_time, app_info_before->last_launch_time);
+  EXPECT_GE(base::Time::Now(), time_before);
 
   app_instance()->SendPackageAppListRefreshed(apps[0].package_name, apps2);
   ValidateHaveAppsAndShortcuts(apps2, shortcuts);
@@ -1661,7 +1662,8 @@
   std::unique_ptr<ArcAppListPrefs::AppInfo> app_info_after =
       prefs->GetApp(app_id);
   ASSERT_TRUE(app_info_after);
-  EXPECT_EQ(now_time, app_info_after->last_launch_time);
+  EXPECT_EQ(app_info_before->last_launch_time,
+            app_info_after->last_launch_time);
 
   RemovePackage(package);
   ValidateHaveAppsAndShortcuts(std::vector<arc::mojom::AppInfo>(),
diff --git a/chrome/browser/ui/app_list/arc/arc_app_utils.cc b/chrome/browser/ui/app_list/arc/arc_app_utils.cc
index 971ee7d..8c52664 100644
--- a/chrome/browser/ui/app_list/arc/arc_app_utils.cc
+++ b/chrome/browser/ui/app_list/arc/arc_app_utils.cc
@@ -166,7 +166,7 @@
     app_instance->LaunchApp(app_info->package_name, app_info->activity,
                             target_rect);
   }
-  prefs->SetLastLaunchTime(app_id, base::Time::Now());
+  prefs->SetLastLaunchTime(app_id);
 
   return true;
 }
@@ -316,7 +316,7 @@
         // deferred launch request when PlayStore item enables Google Play
         // Store.
         if (app_id == kPlayStoreAppId) {
-          prefs->SetLastLaunchTime(app_id, base::Time::Now());
+          prefs->SetLastLaunchTime(app_id);
           return true;
         }
       } else {
@@ -334,7 +334,7 @@
         // deferred launch request when PlayStore item enables Google Play
         // Store.
         if (app_id == kPlayStoreAppId) {
-          prefs->SetLastLaunchTime(app_id, base::Time::Now());
+          prefs->SetLastLaunchTime(app_id);
           return true;
         }
       }
@@ -353,7 +353,7 @@
       // tries to launch an ARC app.
       SetArcCpuRestriction(false);
     }
-    prefs->SetLastLaunchTime(app_id, base::Time::Now());
+    prefs->SetLastLaunchTime(app_id);
     return true;
   }
   return (new AppLauncher(context, app_id, launch_intent, landscape_layout,
diff --git a/chrome/browser/ui/ash/keyboard_controller_browsertest.cc b/chrome/browser/ui/ash/keyboard_controller_browsertest.cc
index f141d8b..b5b6bbf 100644
--- a/chrome/browser/ui/ash/keyboard_controller_browsertest.cc
+++ b/chrome/browser/ui/ash/keyboard_controller_browsertest.cc
@@ -57,7 +57,7 @@
     input_method->ShowImeIfNeeded();
     // Mock window.resizeTo that is expected to be called after navigate to a
     // new virtual keyboard.
-    ui()->GetKeyboardWindow()->SetBounds(init_bounds);
+    ui()->GetContentsWindow()->SetBounds(init_bounds);
   }
 
   void FocusNonEditableNode() {
@@ -72,7 +72,7 @@
     keyboard::KeyboardController::GetInstance()->Reload();
     // Mock window.resizeTo that is expected to be called after navigate to a
     // new virtual keyboard.
-    ui()->GetKeyboardWindow()->SetBounds(init_bounds);
+    ui()->GetContentsWindow()->SetBounds(init_bounds);
   }
 
   bool IsKeyboardVisible() const {
@@ -130,7 +130,7 @@
             keyboard_bounds.height() + keyboard_bounds.y());
   controller->SetKeyboardMode(keyboard::FLOATING);
   // Move keyboard to a random place.
-  ui()->GetKeyboardWindow()->SetBounds(gfx::Rect(50, 50, 50, 50));
+  ui()->GetContentsWindow()->SetBounds(gfx::Rect(50, 50, 50, 50));
   EXPECT_EQ(gfx::Rect(50, 50, 50, 50),
             controller->GetContainerWindow()->bounds());
 
@@ -201,7 +201,7 @@
   keyboard::KeyboardController* controller =
       keyboard::KeyboardController::GetInstance();
   controller->ShowKeyboard(true);
-  controller->ui()->GetKeyboardWindow()->SetBounds(test_bounds);
+  controller->ui()->GetContentsWindow()->SetBounds(test_bounds);
   gfx::Rect keyboard_bounds = controller->GetContainerWindow()->bounds();
   // Starts overscroll.
   controller->NotifyKeyboardBoundsChanging(keyboard_bounds);
diff --git a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
index 4ce5366..f028e30 100644
--- a/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
+++ b/chrome/browser/ui/autofill/save_card_bubble_controller_impl.cc
@@ -88,7 +88,8 @@
       pref_service_->GetInteger(
           prefs::kAutofillAcceptSaveCreditCardPromptState));
 
-  if (!LegalMessageLine::Parse(*legal_message, &legal_message_lines_)) {
+  if (!LegalMessageLine::Parse(*legal_message, &legal_message_lines_,
+                               /*escape_apostrophes=*/true)) {
     AutofillMetrics::LogSaveCardPromptMetric(
         AutofillMetrics::SAVE_CARD_PROMPT_END_INVALID_LEGAL_MESSAGE,
         is_uploading_, is_reshow_,
diff --git a/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.cc b/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.cc
index 23196c2..5174b48 100644
--- a/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.cc
+++ b/chrome/browser/ui/sync/tab_contents_synced_tab_delegate.cc
@@ -114,9 +114,13 @@
     sessions::SerializedNavigationEntry* serialized_entry) const {
   NavigationEntry* entry = GetPossiblyPendingEntryAtIndex(web_contents_, i);
   if (entry) {
+    // Explicitly exclude page state when serializing the navigation entry.
+    // Sync ignores the page state anyway (e.g. form data is not synced), and
+    // the page state can be expensive to serialize.
     *serialized_entry =
         sessions::ContentSerializedNavigationBuilder::FromNavigationEntry(
-            i, *entry);
+            i, *entry,
+            sessions::ContentSerializedNavigationBuilder::EXCLUDE_PAGE_STATE);
   }
 }
 
diff --git a/chrome/browser/ui/views/conflicting_module_view_win.cc b/chrome/browser/ui/views/conflicting_module_view_win.cc
index 7fbd051..ef4dd98d 100644
--- a/chrome/browser/ui/views/conflicting_module_view_win.cc
+++ b/chrome/browser/ui/views/conflicting_module_view_win.cc
@@ -106,6 +106,10 @@
   bubble_shown.SetValue(bubble_shown.GetValue() + 1);
 }
 
+ui::AXRole ConflictingModuleView::GetAccessibleWindowRole() const {
+  return ui::AX_ROLE_ALERT_DIALOG;
+}
+
 void ConflictingModuleView::OnWidgetClosing(views::Widget* widget) {
   views::BubbleDialogDelegateView::OnWidgetClosing(widget);
   base::RecordAction(
@@ -156,10 +160,6 @@
       EnumerateModulesModel::ACTION_BOUNDARY);
 }
 
-void ConflictingModuleView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
-  node_data->role = ui::AX_ROLE_ALERT_DIALOG;
-}
-
 void ConflictingModuleView::OnConflictsAcknowledged() {
   EnumerateModulesModel* model = EnumerateModulesModel::GetInstance();
   if (!model->ShouldShowConflictWarning())
diff --git a/chrome/browser/ui/views/conflicting_module_view_win.h b/chrome/browser/ui/views/conflicting_module_view_win.h
index 721188e1..fbe7055 100644
--- a/chrome/browser/ui/views/conflicting_module_view_win.h
+++ b/chrome/browser/ui/views/conflicting_module_view_win.h
@@ -32,15 +32,13 @@
   // Shows the bubble and updates the counter for how often it has been shown.
   void ShowBubble();
 
-  // views::BubbleDialogDelegateView implementation:
+  // views::BubbleDialogDelegateView:
+  ui::AXRole GetAccessibleWindowRole() const override;
   void OnWidgetClosing(views::Widget* widget) override;
   bool Accept() override;
   base::string16 GetDialogButtonLabel(ui::DialogButton button) const override;
   void Init() override;
 
-  // views::View implementation.
-  void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
-
   // EnumerateModulesModel::Observer:
   void OnConflictsAcknowledged() override;
 
diff --git a/chrome/browser/ui/views/extensions/extension_message_bubble_view_browsertest.cc b/chrome/browser/ui/views/extensions/extension_message_bubble_view_browsertest.cc
index 935df03d..696620c 100644
--- a/chrome/browser/ui/views/extensions/extension_message_bubble_view_browsertest.cc
+++ b/chrome/browser/ui/views/extensions/extension_message_bubble_view_browsertest.cc
@@ -132,7 +132,7 @@
   // platform events may happen before the close completes and the dialog needs
   // to report a valid state.
   ui::AXNodeData node_data;
-  bubble->GetAccessibleNodeData(&node_data);
+  bubble->GetWidget()->GetRootView()->GetAccessibleNodeData(&node_data);
   EXPECT_EQ(ui::AX_ROLE_DIALOG, node_data.role);
 }
 
diff --git a/chrome/browser/ui/views/payments/payment_method_view_controller.cc b/chrome/browser/ui/views/payments/payment_method_view_controller.cc
index bd161ce..fedfc5b 100644
--- a/chrome/browser/ui/views/payments/payment_method_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_method_view_controller.cc
@@ -67,9 +67,12 @@
                                      state,
                                      list,
                                      selected,
+                                     /*clickable=*/true,
                                      /*show_edit_button=*/true),
         instrument_(instrument),
-        dialog_(dialog) {}
+        dialog_(dialog) {
+    Init();
+  }
   ~PaymentMethodListItem() override {}
 
  private:
@@ -144,9 +147,8 @@
     }
   }
 
-  bool IsEnabled() override {
-    // All items are enabled.
-    return true;
+  base::string16 GetNameForDataType() override {
+    return l10n_util::GetStringUTF16(IDS_PAYMENTS_METHOD_OF_PAYMENT_LABEL);
   }
 
   bool CanBeSelected() override {
diff --git a/chrome/browser/ui/views/payments/payment_request_item_list.cc b/chrome/browser/ui/views/payments/payment_request_item_list.cc
index a68ccff..a6347673 100644
--- a/chrome/browser/ui/views/payments/payment_request_item_list.cc
+++ b/chrome/browser/ui/views/payments/payment_request_item_list.cc
@@ -5,7 +5,6 @@
 #include "chrome/browser/ui/views/payments/payment_request_item_list.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 "components/payments/content/payment_request_state.h"
 #include "components/strings/grit/components_strings.h"
@@ -27,7 +26,18 @@
 
 namespace {
 
-const SkColor kCheckmarkColor = 0xFF609265;
+constexpr SkColor kCheckmarkColor = 0xFF609265;
+
+constexpr gfx::Insets kRowInsets = gfx::Insets(
+    kPaymentRequestRowVerticalInsets,
+    kPaymentRequestRowHorizontalInsets,
+    kPaymentRequestRowVerticalInsets,
+    kPaymentRequestRowHorizontalInsets + kPaymentRequestRowExtraRightInset);
+
+// The space between the checkmark, extra view, and edit button.
+constexpr int kExtraViewSpacing = 16;
+
+constexpr int kEditIconSize = 16;
 
 }  // namespace
 
@@ -35,8 +45,10 @@
                                    PaymentRequestState* state,
                                    PaymentRequestItemList* list,
                                    bool selected,
+                                   bool clickable,
                                    bool show_edit_button)
-    : spec_(spec),
+    : PaymentRequestRowView(this, clickable, kRowInsets),
+      spec_(spec),
       state_(state),
       list_(list),
       selected_(selected),
@@ -44,20 +56,12 @@
 
 PaymentRequestItemList::Item::~Item() {}
 
-std::unique_ptr<views::View> PaymentRequestItemList::Item::CreateItemView() {
-  base::string16 accessible_content;
-  std::unique_ptr<views::View> content = CreateContentView(&accessible_content);
+void PaymentRequestItemList::Item::Init() {
+  std::unique_ptr<views::View> content =
+      CreateContentView(&accessible_item_description_);
 
-  const gfx::Insets row_insets(
-      kPaymentRequestRowVerticalInsets, kPaymentRequestRowHorizontalInsets,
-      kPaymentRequestRowVerticalInsets,
-      kPaymentRequestRowHorizontalInsets + kPaymentRequestRowExtraRightInset);
-  std::unique_ptr<PaymentRequestRowView> row =
-      base::MakeUnique<PaymentRequestRowView>(this,
-                                              /* clickable= */ IsEnabled(),
-                                              row_insets);
-  views::GridLayout* layout = new views::GridLayout(row.get());
-  row->SetLayoutManager(layout);
+  views::GridLayout* layout = new views::GridLayout(this);
+  SetLayoutManager(layout);
 
   // Add a column for the item's content view.
   views::ColumnSet* columns = layout->AddColumnSet(0);
@@ -68,8 +72,6 @@
   columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER, 0,
                      views::GridLayout::USE_PREF, 0, 0);
 
-  // The space between the checkmark, extra view, and edit button.
-  constexpr int kExtraViewSpacing = 16;
   std::unique_ptr<views::View> extra_view = CreateExtraView();
   if (extra_view) {
     columns->AddPaddingColumn(0, kExtraViewSpacing);
@@ -78,7 +80,6 @@
                        0, views::GridLayout::USE_PREF, 0, 0);
   }
 
-  constexpr int kEditIconSize = 16;
   if (show_edit_button_) {
     columns->AddPaddingColumn(0, kExtraViewSpacing);
     // Add a column for the edit_button if it exists.
@@ -91,7 +92,7 @@
   content->set_can_process_events_within_subtree(false);
   layout->AddView(content.release());
 
-  checkmark_ = CreateCheckmark(selected() && IsEnabled());
+  checkmark_ = CreateCheckmark(selected() && clickable());
   layout->AddView(checkmark_.get());
 
   if (extra_view)
@@ -112,11 +113,7 @@
     layout->AddView(edit_button);
   }
 
-  row->SetAccessibleName(
-      l10n_util::GetStringFUTF16(IDS_PAYMENTS_ROW_ACCESSIBLE_NAME_FORMAT,
-                                 accessible_content, base::string16()));
-
-  return std::move(row);
+  UpdateAccessibleName();
 }
 
 void PaymentRequestItemList::Item::SetSelected(bool selected, bool notify) {
@@ -127,6 +124,8 @@
   if (checkmark_)
     checkmark_->SetVisible(selected_);
 
+  UpdateAccessibleName();
+
   if (notify)
     SelectedStateChanged();
 }
@@ -141,6 +140,7 @@
   checkmark->SetImage(
       gfx::CreateVectorIcon(views::kMenuCheckIcon, kCheckmarkColor));
   checkmark->SetVisible(selected);
+  checkmark->SetFocusBehavior(views::View::FocusBehavior::NEVER);
   return checkmark;
 }
 
@@ -159,6 +159,17 @@
   }
 }
 
+void PaymentRequestItemList::Item::UpdateAccessibleName() {
+  base::string16 accessible_content =
+      selected_ ? l10n_util::GetStringFUTF16(
+                      IDS_PAYMENTS_ROW_ACCESSIBLE_NAME_SELECTED_FORMAT,
+                      GetNameForDataType(), accessible_item_description_)
+                : l10n_util::GetStringFUTF16(
+                      IDS_PAYMENTS_ROW_ACCESSIBLE_NAME_FORMAT,
+                      GetNameForDataType(), accessible_item_description_);
+  SetAccessibleName(accessible_content);
+}
+
 PaymentRequestItemList::PaymentRequestItemList() : selected_item_(nullptr) {}
 
 PaymentRequestItemList::~PaymentRequestItemList() {}
@@ -174,6 +185,10 @@
   }
 }
 
+void PaymentRequestItemList::Clear() {
+  items_.clear();
+}
+
 std::unique_ptr<views::View> PaymentRequestItemList::CreateListView() {
   std::unique_ptr<views::View> content_view = base::MakeUnique<views::View>();
 
@@ -183,7 +198,7 @@
   content_view->SetLayoutManager(layout);
 
   for (auto& item : items_)
-    content_view->AddChildView(item->CreateItemView().release());
+    content_view->AddChildView(item.release());
 
   return content_view;
 }
diff --git a/chrome/browser/ui/views/payments/payment_request_item_list.h b/chrome/browser/ui/views/payments/payment_request_item_list.h
index e173efb..5e085c5 100644
--- a/chrome/browser/ui/views/payments/payment_request_item_list.h
+++ b/chrome/browser/ui/views/payments/payment_request_item_list.h
@@ -9,6 +9,7 @@
 #include <vector>
 
 #include "base/macros.h"
+#include "chrome/browser/ui/views/payments/payment_request_row_view.h"
 #include "ui/views/controls/button/button.h"
 
 namespace views {
@@ -29,14 +30,16 @@
 class PaymentRequestItemList {
  public:
   // Represents an item in the item list.
-  class Item : public views::ButtonListener {
+  class Item : public views::ButtonListener, public PaymentRequestRowView {
    public:
     // Creates an item that will be owned by |list| with the initial state set
-    // to |selected|.
+    // to |selected|. |clickable| indicates whether or not the user can interact
+    // with this row.
     Item(PaymentRequestSpec* spec,
          PaymentRequestState* state,
          PaymentRequestItemList* list,
          bool selected,
+         bool clickable,
          bool show_edit_button);
     ~Item() override;
 
@@ -57,6 +60,11 @@
     PaymentRequestState* state() { return state_; }
 
    protected:
+    // Initializes the layout and content of the row. Must be called by subclass
+    // constructors, so that virtual methods providing row contents are
+    // accessible.
+    void Init();
+
     // Called when the selected state of this item changes. Subclasses may
     // assume that they are the only selected item in |list| when this is
     // called. This could be called before CreateItemView so subclasses should
@@ -78,9 +86,10 @@
     // item's view, such as the credit card icon.
     virtual std::unique_ptr<views::View> CreateExtraView();
 
-    // Whether the item should be enabled (if disabled, the user will not be
-    // able to click on the item).
-    virtual bool IsEnabled() = 0;
+    // Returns a string describing the type of data for which this row
+    // represents an instance. e.g., "credit card" or "billing address". Used
+    // when describing the row for accessibility.
+    virtual base::string16 GetNameForDataType() = 0;
 
     // Returns whether this item is complete/valid and can be selected by the
     // user. If this returns false when the user attempts to select this item,
@@ -99,10 +108,15 @@
     // views::ButtonListener:
     void ButtonPressed(views::Button* sender, const ui::Event& event) override;
 
+    // Updates the accessible description of this item to reflect its current
+    // status (selected/not).
+    void UpdateAccessibleName();
+
     PaymentRequestSpec* spec_;
     PaymentRequestState* state_;
     PaymentRequestItemList* list_;
     std::unique_ptr<views::ImageView> checkmark_;
+    base::string16 accessible_item_description_;
     bool selected_;
     bool show_edit_button_;
 
@@ -115,6 +129,9 @@
   // Adds an item to this list. |item->list()| should return this object.
   void AddItem(std::unique_ptr<Item> item);
 
+  // Removes all items which have been added.
+  void Clear();
+
   // Creates and returns the UI representation of this list. It iterates over
   // the items it contains, creates their associated views, and adds them to the
   // hierarchy.
diff --git a/chrome/browser/ui/views/payments/payment_request_item_list_unittest.cc b/chrome/browser/ui/views/payments/payment_request_item_list_unittest.cc
index e54e27a3..832d0fa 100644
--- a/chrome/browser/ui/views/payments/payment_request_item_list_unittest.cc
+++ b/chrome/browser/ui/views/payments/payment_request_item_list_unittest.cc
@@ -23,8 +23,11 @@
                                      nullptr,
                                      list,
                                      selected,
+                                     /*clickable=*/true,
                                      /*show_edit_button=*/false),
-        selected_state_changed_calls_count_(0) {}
+        selected_state_changed_calls_count_(0) {
+    Init();
+  }
 
   int selected_state_changed_calls_count() {
     return selected_state_changed_calls_count_;
@@ -36,7 +39,7 @@
     return base::MakeUnique<views::View>();
   }
 
-  bool IsEnabled() override { return true; }
+  base::string16 GetNameForDataType() override { return base::string16(); }
 
   bool CanBeSelected() override { return true; }
 
diff --git a/chrome/browser/ui/views/payments/payment_request_row_view.cc b/chrome/browser/ui/views/payments/payment_request_row_view.cc
index fbe5a09..c70f7458 100644
--- a/chrome/browser/ui/views/payments/payment_request_row_view.cc
+++ b/chrome/browser/ui/views/payments/payment_request_row_view.cc
@@ -53,7 +53,7 @@
 
 // views::CustomButton:
 void PaymentRequestRowView::StateChanged(ButtonState old_state) {
-  if (!clickable_)
+  if (!clickable())
     return;
 
   SetIsHighlighted(state() == views::Button::STATE_HOVERED ||
@@ -61,14 +61,14 @@
 }
 
 void PaymentRequestRowView::OnFocus() {
-  if (clickable_) {
+  if (clickable()) {
     SetIsHighlighted(true);
     SchedulePaint();
   }
 }
 
 void PaymentRequestRowView::OnBlur() {
-  if (clickable_) {
+  if (clickable()) {
     SetIsHighlighted(false);
     SchedulePaint();
   }
diff --git a/chrome/browser/ui/views/payments/payment_request_row_view.h b/chrome/browser/ui/views/payments/payment_request_row_view.h
index 3fff961..20ea490 100644
--- a/chrome/browser/ui/views/payments/payment_request_row_view.h
+++ b/chrome/browser/ui/views/payments/payment_request_row_view.h
@@ -21,6 +21,9 @@
                         const gfx::Insets& insets);
   ~PaymentRequestRowView() override;
 
+ protected:
+  bool clickable() { return clickable_; }
+
  private:
   // Sets this row's background to the theme's hovered color to indicate that
   // it's begin hovered or it's focused.
diff --git a/chrome/browser/ui/views/payments/payment_request_sheet_controller.h b/chrome/browser/ui/views/payments/payment_request_sheet_controller.h
index b8aab2c..214863d 100644
--- a/chrome/browser/ui/views/payments/payment_request_sheet_controller.h
+++ b/chrome/browser/ui/views/payments/payment_request_sheet_controller.h
@@ -58,6 +58,9 @@
   // Caller should not take ownership of the result.
   PaymentRequestDialogView* dialog() { return dialog_; }
 
+  // Returns the title to be displayed in this sheet's header.
+  virtual base::string16 GetSheetTitle() = 0;
+
  protected:
   // Clears the content part of the view represented by this view controller and
   // calls FillContentView again to re-populate it with updated views.
@@ -90,9 +93,6 @@
   // to the title.
   virtual bool ShouldShowHeaderBackArrow();
 
-  // Returns the title to be displayed in this sheet's header.
-  virtual base::string16 GetSheetTitle() = 0;
-
   // Implemented by subclasses to populate |content_view| with the views that
   // should be displayed in their content area (between the header and the
   // footer). This may be called at view creation time as well as anytime
diff --git a/chrome/browser/ui/views/payments/profile_list_view_controller.cc b/chrome/browser/ui/views/payments/profile_list_view_controller.cc
index 1da06e3..90ee5c1 100644
--- a/chrome/browser/ui/views/payments/profile_list_view_controller.cc
+++ b/chrome/browser/ui/views/payments/profile_list_view_controller.cc
@@ -48,21 +48,26 @@
   // are represented by the current instance of the dialog. |parent_view| points
   // to the controller which owns |parent_list|. |profile| is the
   // AutofillProfile that this specific list item represents. It's a cached
-  // profile owned by |state|.
+  // profile owned by |state|. |clickable| indicates whether or not this profile
+  // can be clicked (i.e., whether it's enabled).
   ProfileItem(autofill::AutofillProfile* profile,
               PaymentRequestSpec* spec,
               PaymentRequestState* state,
               PaymentRequestItemList* parent_list,
               ProfileListViewController* controller,
               PaymentRequestDialogView* dialog,
-              bool selected)
+              bool selected,
+              bool clickable)
       : PaymentRequestItemList::Item(spec,
                                      state,
                                      parent_list,
                                      selected,
+                                     clickable,
                                      /*show_edit_button=*/true),
         controller_(controller),
-        profile_(profile) {}
+        profile_(profile) {
+    Init();
+  }
   ~ProfileItem() override {}
 
  private:
@@ -81,18 +86,20 @@
     }
   }
 
-  bool IsEnabled() override { return controller_->IsEnabled(profile_); }
+  base::string16 GetNameForDataType() override {
+    return controller_->GetSheetTitle();
+  }
 
   bool CanBeSelected() override {
     // In order to be selectable, a profile entry needs to be enabled, and the
     // profile valid according to the controller. If either condition is false,
     // PerformSelectionFallback() is called.
-    return IsEnabled() && controller_->IsValidProfile(*profile_);
+    return clickable() && controller_->IsValidProfile(*profile_);
   }
 
   void PerformSelectionFallback() override {
     // If enabled, the editor is opened to complete the invalid profile.
-    if (IsEnabled())
+    if (clickable())
       controller_->ShowEditor(profile_);
   }
 
@@ -253,6 +260,7 @@
         dialog()->GoBack();
       } else {
         // The error profile is known, refresh the view to display it correctly.
+        PopulateList();
         UpdateContentView();
       }
     }
@@ -375,12 +383,12 @@
 void ProfileListViewController::PopulateList() {
   autofill::AutofillProfile* selected_profile = GetSelectedProfile();
 
-  // This must be done at Create-time, rather than construct-time, because
-  // the subclass method GetProfiles can't be called in the ctor.
+  list_.Clear();
+
   for (auto* profile : GetProfiles()) {
-    list_.AddItem(base::MakeUnique<ProfileItem>(profile, spec(), state(),
-                                                &list_, this, dialog(),
-                                                profile == selected_profile));
+    list_.AddItem(base::MakeUnique<ProfileItem>(
+        profile, spec(), state(), &list_, this, dialog(),
+        profile == selected_profile, IsEnabled(profile)));
   }
 }
 
diff --git a/chrome/browser/ui/views/payments/shipping_option_view_controller.cc b/chrome/browser/ui/views/payments/shipping_option_view_controller.cc
index d8ed2739..99d1edf 100644
--- a/chrome/browser/ui/views/payments/shipping_option_view_controller.cc
+++ b/chrome/browser/ui/views/payments/shipping_option_view_controller.cc
@@ -9,6 +9,8 @@
 #include "components/payments/content/payment_request_spec.h"
 #include "components/payments/content/payment_request_state.h"
 #include "components/payments/core/strings_util.h"
+#include "components/strings/grit/components_strings.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/views/layout/fill_layout.h"
 
 namespace payments {
@@ -27,8 +29,11 @@
                                      state,
                                      parent_list,
                                      selected,
+                                     /*clickable=*/true,
                                      /*show_edit_button=*/false),
-        shipping_option_(shipping_option) {}
+        shipping_option_(shipping_option) {
+    Init();
+  }
   ~ShippingOptionItem() override {}
 
  private:
@@ -47,9 +52,8 @@
     }
   }
 
-  bool IsEnabled() override {
-    // Shipping options are vetted by the website; none are disabled.
-    return true;
+  base::string16 GetNameForDataType() override {
+    return l10n_util::GetStringUTF16(IDS_PAYMENTS_SHIPPING_OPTION_LABEL);
   }
 
   bool CanBeSelected() override {
diff --git a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc
index b20417ac..671dfa8 100644
--- a/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc
+++ b/chrome/browser/ui/views/permission_bubble/permission_prompt_impl.cc
@@ -58,11 +58,11 @@
   void CloseBubble();
 
   // BubbleDialogDelegateView:
+  ui::AXRole GetAccessibleWindowRole() const override;
   bool ShouldShowCloseButton() const override;
   base::string16 GetWindowTitle() const override;
   void AddedToWidget() override;
   void OnWidgetDestroying(views::Widget* widget) override;
-  void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
   bool Cancel() override;
   bool Accept() override;
   bool Close() override;
@@ -147,6 +147,11 @@
   GetWidget()->Close();
 }
 
+ui::AXRole PermissionsBubbleDialogDelegateView::GetAccessibleWindowRole()
+    const {
+  return ui::AX_ROLE_ALERT_DIALOG;
+}
+
 bool PermissionsBubbleDialogDelegateView::ShouldShowCloseButton() const {
   return true;
 }
@@ -177,12 +182,6 @@
   }
 }
 
-void PermissionsBubbleDialogDelegateView::GetAccessibleNodeData(
-    ui::AXNodeData* node_data) {
-  views::BubbleDialogDelegateView::GetAccessibleNodeData(node_data);
-  node_data->role = ui::AX_ROLE_ALERT_DIALOG;
-}
-
 int PermissionsBubbleDialogDelegateView::GetDefaultDialogButton() const {
   // To prevent permissions being accepted accidentally, and as a security
   // measure against crbug.com/619429, permission prompts should not be accepted
diff --git a/chrome/browser/ui/webui/extensions/extensions_ui.cc b/chrome/browser/ui/webui/extensions/extensions_ui.cc
index b41e3e0..7cefb0f 100644
--- a/chrome/browser/ui/webui/extensions/extensions_ui.cc
+++ b/chrome/browser/ui/webui/extensions/extensions_ui.cc
@@ -115,6 +115,10 @@
   source->AddLocalizedString("sidebarApps", IDS_MD_EXTENSIONS_SIDEBAR_APPS);
   source->AddLocalizedString("sidebarExtensions",
                              IDS_MD_EXTENSIONS_SIDEBAR_EXTENSIONS);
+  source->AddLocalizedString("noExtensionsOrApps",
+                             IDS_MD_EXTENSIONS_NO_INSTALLED_ITEMS);
+  source->AddLocalizedString("noSearchResults",
+                             IDS_MD_EXTENSIONS_NO_SEARCH_RESULTS);
   source->AddLocalizedString("dropToInstall",
                              IDS_EXTENSIONS_INSTALL_DROP_TARGET);
   source->AddLocalizedString("errorsPageHeading",
diff --git a/chrome/browser/ui/webui/options/browser_options_handler.cc b/chrome/browser/ui/webui/options/browser_options_handler.cc
index 318d10a..ac9aad5 100644
--- a/chrome/browser/ui/webui/options/browser_options_handler.cc
+++ b/chrome/browser/ui/webui/options/browser_options_handler.cc
@@ -293,8 +293,6 @@
     {"downloadLocationGroupName", IDS_OPTIONS_DOWNLOADLOCATION_GROUP_NAME},
     {"easyUnlockDescription", IDS_OPTIONS_EASY_UNLOCK_DESCRIPTION,
      device_type_resource_id},
-    {"easyUnlockRequireProximityLabel",
-     IDS_OPTIONS_EASY_UNLOCK_REQUIRE_PROXIMITY_LABEL, device_type_resource_id},
     {"easyUnlockSectionTitle", IDS_OPTIONS_EASY_UNLOCK_SECTION_TITLE},
     {"easyUnlockSetupButton", IDS_OPTIONS_EASY_UNLOCK_SETUP_BUTTON},
     {"easyUnlockSetupIntro", IDS_OPTIONS_EASY_UNLOCK_SETUP_INTRO,
@@ -762,9 +760,6 @@
   values->SetBoolean(
       "easyUnlockAllowed", EasyUnlockService::Get(profile)->IsAllowed());
   values->SetString("easyUnlockLearnMoreURL", chrome::kEasyUnlockLearnMoreUrl);
-  values->SetBoolean("easyUnlockProximityDetectionAllowed",
-                     base::CommandLine::ForCurrentProcess()->HasSwitch(
-                         proximity_auth::switches::kEnableProximityDetection));
 
 #if defined(OS_CHROMEOS)
   RegisterTitle(values, "thirdPartyImeConfirmOverlay",
diff --git a/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc b/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc
index 299d20bd..e761bea 100644
--- a/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc
+++ b/chrome/browser/ui/webui/settings/chromeos/easy_unlock_settings_handler.cc
@@ -40,11 +40,6 @@
   if (!allowed)
     return nullptr;
 
-  html_source->AddBoolean(
-      "easyUnlockProximityDetectionAllowed",
-      base::CommandLine::ForCurrentProcess()->HasSwitch(
-          proximity_auth::switches::kEnableProximityDetection));
-
   return new EasyUnlockSettingsHandler(profile);
 }
 
diff --git a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
index 08ea3dd..d6659782 100644
--- a/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
+++ b/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc
@@ -921,10 +921,6 @@
       "easyUnlockTurnOffDescription",
       l10n_util::GetStringFUTF16(IDS_SETTINGS_EASY_UNLOCK_TURN_OFF_DESCRIPTION,
                                  device_name));
-  html_source->AddString(
-      "easyUnlockRequireProximityLabel",
-      l10n_util::GetStringFUTF16(
-          IDS_SETTINGS_EASY_UNLOCK_REQUIRE_PROXIMITY_LABEL, device_name));
 
   html_source->AddString("easyUnlockLearnMoreURL",
                          chrome::kEasyUnlockLearnMoreUrl);
diff --git a/chrome/browser/vr/ui_interface.h b/chrome/browser/vr/ui_interface.h
index fde6f7f..f31e22d 100644
--- a/chrome/browser/vr/ui_interface.h
+++ b/chrome/browser/vr/ui_interface.h
@@ -41,6 +41,7 @@
   virtual void SetScreenCapturingIndicator(bool enabled) = 0;
   virtual void SetAudioCapturingIndicator(bool enabled) = 0;
   virtual void SetBluetoothConnectedIndicator(bool enabled) = 0;
+  virtual void SetLocationAccessIndicator(bool enabled) = 0;
   virtual void SetSplashScreenIcon(const SkBitmap& bitmap) = 0;
 
   // Tab handling.
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 07e766f..01dead6 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -1335,10 +1335,6 @@
 // Preference storing Easy Unlock pairing data.
 const char kEasyUnlockPairing[] = "easy_unlock.pairing";
 
-// Whether close proximity between the remote and the local device is required
-// in order to use Easy Unlock.
-const char kEasyUnlockProximityRequired[] = "easy_unlock.proximity_required";
-
 #if BUILDFLAG(ENABLE_EXTENSIONS)
 // Used to indicate whether or not the toolbar redesign bubble has been shown
 // and acknowledged, and the last time the bubble was shown.
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 16dc991..25fe0b6 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -461,7 +461,6 @@
 extern const char kEasyUnlockAllowed[];
 extern const char kEasyUnlockEnabled[];
 extern const char kEasyUnlockPairing[];
-extern const char kEasyUnlockProximityRequired[];
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
 extern const char kToolbarIconSurfacingBubbleAcknowledged[];
diff --git a/chrome/common/profiling/BUILD.gn b/chrome/common/profiling/BUILD.gn
index b455adbb..4cf2ed4 100644
--- a/chrome/common/profiling/BUILD.gn
+++ b/chrome/common/profiling/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 import("//chrome/common/features.gni")
+import("//mojo/public/tools/bindings/mojom.gni")
 
 if (enable_oop_heap_profiling) {
   static_library("profiling") {
@@ -18,14 +19,23 @@
       "memlog_sender_pipe_win.h",
       "memlog_stream.cc",
       "memlog_stream.h",
+      "profiling_constants.cc",
+      "profiling_constants.h",
     ]
 
     deps = [
+      ":interfaces",
       "//base",
       "//base:debugging_flags",
       "//chrome/common:constants",
     ]
   }
+
+  mojom("interfaces") {
+    sources = [
+      "profiling_control.mojom",
+    ]
+  }
 } else {
   # Dummy group so this target can be unconditionally depended on.
   group("profiling") {
diff --git a/chrome/common/profiling/OWNERS b/chrome/common/profiling/OWNERS
new file mode 100644
index 0000000..08850f4
--- /dev/null
+++ b/chrome/common/profiling/OWNERS
@@ -0,0 +1,2 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chrome/common/profiling/memlog_allocator_shim.cc b/chrome/common/profiling/memlog_allocator_shim.cc
index 346837f5..34671825 100644
--- a/chrome/common/profiling/memlog_allocator_shim.cc
+++ b/chrome/common/profiling/memlog_allocator_shim.cc
@@ -13,6 +13,10 @@
 #include "build/build_config.h"
 #include "chrome/common/profiling/memlog_stream.h"
 
+#if defined(OS_POSIX)
+#include <limits.h>
+#endif
+
 namespace profiling {
 
 namespace {
@@ -25,14 +29,20 @@
 // to raise this to avoid truncation. This matches the current value in the
 // in-process heap profiler (heap_profiler_allocation_context.h) so the two
 // systems performance and memory overhead can be compared consistently.
-const int kMaxStackEntries = 48;
+constexpr int kMaxStackEntries = 48;
 
+#if defined(OS_WIN)
 // Matches the native buffer size on the pipe.
-const int kSendBufferSize = 65536;
+constexpr int kSendBufferSize = 65536;
+#else
+// Writes on Posix greater than PIPE_BUF are not guaranteed to be atomic so
+// our buffers can't be larger than that.
+constexpr int kSendBufferSize = PIPE_BUF;
+#endif
 
 // Prime since this is used like a hash table. Numbers of this magnitude seemed
 // to provide sufficient parallelism to avoid lock overhead in ad-hoc testing.
-const int kNumSendBuffers = 17;
+constexpr int kNumSendBuffers = 17;
 
 class SendBuffer {
  public:
diff --git a/chrome/common/profiling/memlog_sender.cc b/chrome/common/profiling/memlog_sender.cc
index 49af001dd7..5e6ed8b 100644
--- a/chrome/common/profiling/memlog_sender.cc
+++ b/chrome/common/profiling/memlog_sender.cc
@@ -12,6 +12,14 @@
 
 namespace profiling {
 
+namespace {
+
+// TODO(brettw) this is a hack to allow StartProfilingMojo to work. Figure out
+// how to get the lifetime of this that allows that function call to work.
+MemlogSenderPipe* memlog_sender_pipe = nullptr;
+
+}  // namespace
+
 void InitMemlogSenderIfNecessary(const base::CommandLine& cmdline) {
   std::string pipe_id = cmdline.GetSwitchValueASCII(switches::kMemlogPipe);
   if (!pipe_id.empty())
@@ -21,13 +29,24 @@
 void StartMemlogSender(const std::string& pipe_id) {
   static MemlogSenderPipe pipe(pipe_id);
   pipe.Connect();
+  memlog_sender_pipe = &pipe;
 
   StreamHeader header;
   header.signature = kStreamSignature;
-
   pipe.Send(&header, sizeof(StreamHeader));
 
   InitAllocatorShim(&pipe);
 }
 
+void StartProfilingMojo() {
+  static bool started_mojo = false;
+
+  if (!started_mojo) {
+    started_mojo = true;
+    StartMojoControlPacket start_mojo_message;
+    start_mojo_message.op = kStartMojoControlPacketType;
+    memlog_sender_pipe->Send(&start_mojo_message, sizeof(start_mojo_message));
+  }
+}
+
 }  // namespace profiling
diff --git a/chrome/common/profiling/memlog_sender.h b/chrome/common/profiling/memlog_sender.h
index bb4b509..84c82441 100644
--- a/chrome/common/profiling/memlog_sender.h
+++ b/chrome/common/profiling/memlog_sender.h
@@ -15,10 +15,18 @@
 
 namespace profiling {
 
+// Starts the memlog sender pipe if the command line has requested it. The pipe
+// ID will be extracted from the command line argument.
 void InitMemlogSenderIfNecessary(const base::CommandLine& cmdline);
 
+// Starts the memlog sender pipe with the given ID.
 void StartMemlogSender(const std::string& pipe_id);
 
+// Tells the profiling process to try to connect to the profiling control
+// channel. This must be done after the browser is ready to accept such a
+// connection.
+void StartProfilingMojo();
+
 }  // namespace profiling
 
 #endif  // CHROME_COMMON_PROFILING_MEMLOG_SENDER_H_
diff --git a/chrome/common/profiling/memlog_sender_pipe_win.cc b/chrome/common/profiling/memlog_sender_pipe_win.cc
index 6ab47c7f..953dbfd2 100644
--- a/chrome/common/profiling/memlog_sender_pipe_win.cc
+++ b/chrome/common/profiling/memlog_sender_pipe_win.cc
@@ -10,7 +10,7 @@
 
 namespace profiling {
 
-MemlogSenderPipe::MemlogSenderPipe(const base::string& pipe_id)
+MemlogSenderPipe::MemlogSenderPipe(const std::string& pipe_id)
     : pipe_id_(base::UTF8ToUTF16(pipe_id)), handle_(INVALID_HANDLE_VALUE) {}
 
 MemlogSenderPipe::~MemlogSenderPipe() {
@@ -28,9 +28,13 @@
   ULONGLONG timeout_ticks = ::GetTickCount64() + kMaxWaitMS;
   do {
     if (!::WaitNamedPipe(pipe_name.c_str(), kMaxWaitMS)) {
-      // Since it will wait "forever", the only time WaitNamedPipe should fail
-      // is if the pipe doesn't exist.
-      return false;
+      // This code will race with the creation of the pipe in the profiling
+      // process. If the pipe doesn't exist yet, wait briefly and try again.
+
+      // TODO(brettw) check for GetLastError() and only do this if the pipe
+      // doesn't exist (other errors should bail).
+      ::Sleep(10);
+      continue;
     }
     // This is a single-direction pipe so we don't specify GENERIC_READ, but
     // MSDN says we need FILE_READ_ATTRIBUTES.
diff --git a/chrome/common/profiling/memlog_sender_pipe_win.h b/chrome/common/profiling/memlog_sender_pipe_win.h
index 6b349c4..285c192f 100644
--- a/chrome/common/profiling/memlog_sender_pipe_win.h
+++ b/chrome/common/profiling/memlog_sender_pipe_win.h
@@ -7,6 +7,8 @@
 
 #include <windows.h>
 
+#include <string>
+
 #include "base/macros.h"
 #include "base/strings/string16.h"
 
@@ -14,7 +16,7 @@
 
 class MemlogSenderPipe {
  public:
-  explicit MemlogSenderPipe(const base::string& pipe_id);
+  explicit MemlogSenderPipe(const std::string& pipe_id);
   ~MemlogSenderPipe();
 
   bool Connect();
diff --git a/chrome/common/profiling/memlog_stream.h b/chrome/common/profiling/memlog_stream.h
index 44557a7..125295f4 100644
--- a/chrome/common/profiling/memlog_stream.h
+++ b/chrome/common/profiling/memlog_stream.h
@@ -11,16 +11,22 @@
 
 namespace profiling {
 
-static const uint32_t kStreamSignature = 0xF6103B71;
+constexpr uint32_t kStreamSignature = 0xF6103B71;
 
-static const uint32_t kAllocPacketType = 0xA1A1A1A1;
-static const uint32_t kFreePacketType = 0xFEFEFEFE;
+constexpr uint32_t kStartMojoControlPacketType = 0x77777777;
+constexpr uint32_t kAllocPacketType = 0xA1A1A1A1;
+constexpr uint32_t kFreePacketType = 0xFEFEFEFE;
 
 #pragma pack(push, 1)
 struct StreamHeader {
+  // TODO(brettw) consider using C++11 default initialization for the types.
   uint32_t signature;  // kStreamSignature
 };
 
+struct StartMojoControlPacket {
+  uint32_t op;  // = kStartMojoControlPacketType
+};
+
 struct AllocPacket {
   uint32_t op;  // = kAllocPacketType
 
diff --git a/chrome/common/profiling/profiling_constants.cc b/chrome/common/profiling/profiling_constants.cc
new file mode 100644
index 0000000..6d47ddb
--- /dev/null
+++ b/chrome/common/profiling/profiling_constants.cc
@@ -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.
+
+#include "chrome/common/profiling/profiling_constants.h"
+
+namespace profiling {
+
+const char kProfilingControlPipeName[] = "memlog_control";
+
+}  // namespace profiling
diff --git a/chrome/common/profiling/profiling_constants.h b/chrome/common/profiling/profiling_constants.h
new file mode 100644
index 0000000..8d55439e8
--- /dev/null
+++ b/chrome/common/profiling/profiling_constants.h
@@ -0,0 +1,15 @@
+// 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_COMMON_PROFILING_PROFILING_CONSTANTS_H_
+#define CHROME_COMMON_PROFILING_PROFILING_CONSTANTS_H_
+
+namespace profiling {
+
+// Name of the profiling control Mojo service.
+extern const char kProfilingControlPipeName[];
+
+}  // namespace profiling
+
+#endif  // CHROME_COMMON_PROFILING_PROFILING_CONSTANTS_H_
diff --git a/chrome/common/profiling/profiling_control.mojom b/chrome/common/profiling/profiling_control.mojom
new file mode 100644
index 0000000..c550b5f
--- /dev/null
+++ b/chrome/common/profiling/profiling_control.mojom
@@ -0,0 +1,12 @@
+// 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 profiling.mojom;
+
+interface ProfilingControl {
+  // Adds a new platform-specific pipe to read memlog trace data from.
+  // In normal usage, each child process launch will have a corresponding call
+  // to this.
+  AddNewSender(handle sender_pipe, int32 sender_pid);
+};
diff --git a/chrome/installer/linux/BUILD.gn b/chrome/installer/linux/BUILD.gn
index e3a1a13..315f8b6 100644
--- a/chrome/installer/linux/BUILD.gn
+++ b/chrome/installer/linux/BUILD.gn
@@ -194,7 +194,7 @@
   # TODO(thomasanderson): Move this variable into a .gni file
   # somewhere.  It is currently copied from
   # buildtools/third_party/libc++/BUILD.gn.
-  libcpp_is_static = !is_component_build && !is_asan && !is_msan && !is_tsan
+  libcpp_is_static = !is_component_build && !using_sanitizer
   if (!libcpp_is_static && use_custom_libcxx) {
     public_deps += [ "//buildtools/third_party/libc++:libc++" ]
   }
@@ -247,7 +247,7 @@
   # TODO(thomasanderson): Move this variable into a .gni file
   # somewhere.  It is currently copied from
   # buildtools/third_party/libc++/BUILD.gn.
-  libcpp_is_static = !is_component_build && !is_asan && !is_msan && !is_tsan
+  libcpp_is_static = !is_component_build && !using_sanitizer
   if (!libcpp_is_static && use_custom_libcxx) {
     packaging_files_binaries += [ "$root_out_dir/libc++.so" ]
   }
diff --git a/chrome/profiling/BUILD.gn b/chrome/profiling/BUILD.gn
index 5cd6cc4..f6c61de 100644
--- a/chrome/profiling/BUILD.gn
+++ b/chrome/profiling/BUILD.gn
@@ -33,6 +33,8 @@
       "profiling_globals.h",
       "profiling_main.cc",
       "profiling_main.h",
+      "profiling_process.cc",
+      "profiling_process.h",
     ]
 
     deps = [
diff --git a/chrome/profiling/memlog_connection_manager.cc b/chrome/profiling/memlog_connection_manager.cc
index a9e43bc..b305b9b 100644
--- a/chrome/profiling/memlog_connection_manager.cc
+++ b/chrome/profiling/memlog_connection_manager.cc
@@ -22,7 +22,11 @@
         pipe(p),
         tracker(std::move(complete_cb)) {}
 
-  ~Connection() {}
+  ~Connection() {
+    // The parser may outlive this class because it's refcounted, make sure no
+    // callbacks are issued.
+    parser->DisconnectReceivers();
+  }
 
   base::Thread thread;
 
@@ -47,6 +51,14 @@
   server_->Start();
 }
 
+void MemlogConnectionManager::OnStartMojoControl() {
+  ProfilingGlobals::Get()->GetIORunner()->PostTask(
+      FROM_HERE,
+      base::Bind(
+          &ProfilingProcess::EnsureMojoStarted,
+          base::Unretained(ProfilingGlobals::Get()->GetProfilingProcess())));
+}
+
 void MemlogConnectionManager::OnNewConnection(
     scoped_refptr<MemlogReceiverPipe> new_pipe) {
   int remote_process = new_pipe->GetRemoteProcessID();
@@ -62,7 +74,7 @@
       std::move(complete_cb), remote_process, new_pipe);
   connection->thread.Start();
 
-  connection->parser = new MemlogStreamParser(&connection->tracker);
+  connection->parser = new MemlogStreamParser(this, &connection->tracker);
   new_pipe->SetReceiver(connection->thread.task_runner(), connection->parser);
 
   connections_[remote_process] = std::move(connection);
diff --git a/chrome/profiling/memlog_connection_manager.h b/chrome/profiling/memlog_connection_manager.h
index 90879aa1..6ad9f209 100644
--- a/chrome/profiling/memlog_connection_manager.h
+++ b/chrome/profiling/memlog_connection_manager.h
@@ -11,6 +11,7 @@
 #include "base/macros.h"
 #include "build/build_config.h"
 #include "chrome/profiling/backtrace_storage.h"
+#include "chrome/profiling/memlog_control_receiver.h"
 #include "chrome/profiling/memlog_receiver_pipe_server.h"
 
 namespace base {
@@ -21,10 +22,10 @@
 
 // Manages all connections and logging for each process. Pipes are supplied by
 // the pipe server and this class will connect them to a parser and logger.
-class MemlogConnectionManager {
+class MemlogConnectionManager : public MemlogControlReceiver {
  public:
   MemlogConnectionManager();
-  ~MemlogConnectionManager();
+  ~MemlogConnectionManager() override;
 
   // Starts listening for connections.
   void StartConnections(const std::string& pipe_id);
@@ -32,6 +33,9 @@
  private:
   struct Connection;
 
+  // MemlogControlReceiver implementation.
+  void OnStartMojoControl() override;
+
   // Called by the pipe server when a new pipe is created.
   void OnNewConnection(scoped_refptr<MemlogReceiverPipe> new_pipe);
 
diff --git a/chrome/profiling/memlog_control_receiver.h b/chrome/profiling/memlog_control_receiver.h
new file mode 100644
index 0000000..21e7838a
--- /dev/null
+++ b/chrome/profiling/memlog_control_receiver.h
@@ -0,0 +1,19 @@
+// 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_PROFILING_MEMLOG_CONTROL_RECEIVER_H_
+#define CHROME_PROFILING_MEMLOG_CONTROL_RECEIVER_H_
+
+namespace profiling {
+
+class MemlogControlReceiver {
+ public:
+  virtual ~MemlogControlReceiver() {}
+
+  virtual void OnStartMojoControl() = 0;
+};
+
+}  // namespace profiling
+
+#endif  // CHROME_PROFILING_MEMLOG_CONTROL_RECEIVER_H_
diff --git a/chrome/profiling/memlog_stream_parser.cc b/chrome/profiling/memlog_stream_parser.cc
index 3fbc60f..793bced 100644
--- a/chrome/profiling/memlog_stream_parser.cc
+++ b/chrome/profiling/memlog_stream_parser.cc
@@ -26,19 +26,30 @@
 
 MemlogStreamParser::Block::~Block() {}
 
-MemlogStreamParser::MemlogStreamParser(MemlogReceiver* receiver)
-    : receiver_(receiver) {}
+MemlogStreamParser::MemlogStreamParser(MemlogControlReceiver* control_receiver,
+                                       MemlogReceiver* receiver)
+    : control_receiver_(control_receiver), receiver_(receiver) {}
 
 MemlogStreamParser::~MemlogStreamParser() {}
 
+void MemlogStreamParser::DisconnectReceivers() {
+  receiver_ = nullptr;
+  control_receiver_ = nullptr;
+}
+
 void MemlogStreamParser::OnStreamData(std::unique_ptr<char[]> data, size_t sz) {
+  if (!receiver_)
+    return;  // When no receiver is connected, do nothing with incoming data.
+
   blocks_.emplace_back(std::move(data), sz);
 
   if (!received_header_) {
     received_header_ = true;
     ReadStatus status = ParseHeader();
-    if (status != READ_OK)
-      return;  // TODO(brettw) signal error.
+    if (status != READ_OK) {
+      LOG(ERROR) << "Memlog header read error.";
+      return;
+    }
   }
 
   while (true) {
@@ -54,16 +65,26 @@
       case kFreePacketType:
         status = ParseFree();
         break;
+      case kStartMojoControlPacketType:
+        ConsumeBytes(sizeof(StartMojoControlPacket));
+        if (control_receiver_)
+          control_receiver_->OnStartMojoControl();
+        status = READ_OK;
+        break;
       default:
-        return;  // TODO(brettw) signal error.
+        LOG(ERROR) << "Error reading memlog message stream" << msg_type;
+        return;
     }
-    if (status != READ_OK)
-      return;  // TODO(brettw) signal error.
+    if (status != READ_OK) {
+      LOG_IF(ERROR, status == READ_ERROR) << "Memlog read error";
+      return;
+    }
   }
 }
 
 void MemlogStreamParser::OnStreamComplete() {
-  receiver_->OnComplete();
+  if (receiver_)
+    receiver_->OnComplete();
 }
 
 bool MemlogStreamParser::AreBytesAvailable(size_t count) const {
diff --git a/chrome/profiling/memlog_stream_parser.h b/chrome/profiling/memlog_stream_parser.h
index 1418d0b..f5f595d 100644
--- a/chrome/profiling/memlog_stream_parser.h
+++ b/chrome/profiling/memlog_stream_parser.h
@@ -8,6 +8,7 @@
 #include <deque>
 
 #include "base/macros.h"
+#include "chrome/profiling/memlog_control_receiver.h"
 #include "chrome/profiling/memlog_receiver.h"
 #include "chrome/profiling/memlog_stream_receiver.h"
 
@@ -16,8 +17,13 @@
 // Parses a memory stream. Refcounted via StreamReceiver.
 class MemlogStreamParser : public MemlogStreamReceiver {
  public:
-  // Receiver must outlive this class.
-  explicit MemlogStreamParser(MemlogReceiver* receiver);
+  // Both receivers must either outlive this class or live until
+  // DisconnectReceivers is called.
+  explicit MemlogStreamParser(MemlogControlReceiver* control_receiver,
+                              MemlogReceiver* receiver);
+
+  // For tear-down, resets both receivers so they will not be called.
+  void DisconnectReceivers();
 
   // StreamReceiver implementation.
   void OnStreamData(std::unique_ptr<char[]> data, size_t sz) override;
@@ -53,7 +59,9 @@
   ReadStatus ParseAlloc();
   ReadStatus ParseFree();
 
-  MemlogReceiver* receiver_;  // Not owned by this class.
+  // Not owned by this class.
+  MemlogControlReceiver* control_receiver_;
+  MemlogReceiver* receiver_;
 
   std::deque<Block> blocks_;
 
diff --git a/chrome/profiling/profiling_globals.cc b/chrome/profiling/profiling_globals.cc
index ec31381..2d97322 100644
--- a/chrome/profiling/profiling_globals.cc
+++ b/chrome/profiling/profiling_globals.cc
@@ -10,26 +10,23 @@
 
 namespace profiling {
 
-ProfilingGlobals::ProfilingGlobals()
-    : io_thread_("IO thread") {
-#if defined(OS_WIN)
-  io_thread_.init_com_with_mta(true);
-#endif
-  base::Thread::Options options;
-  options.message_loop_type = base::MessageLoop::TYPE_IO;
-  io_thread_.StartWithOptions(options);
+ProfilingGlobals* ProfilingGlobals::singleton_ = nullptr;
+
+ProfilingGlobals::ProfilingGlobals() {
+  DCHECK(!singleton_);
+  singleton_ = this;
 }
 
-ProfilingGlobals::~ProfilingGlobals() {}
-
-// static
-ProfilingGlobals* ProfilingGlobals::Get() {
-  static ProfilingGlobals singleton;
-  return &singleton;
+ProfilingGlobals::~ProfilingGlobals() {
+  singleton_ = nullptr;
 }
 
 base::TaskRunner* ProfilingGlobals::GetIORunner() {
-  return io_thread_.task_runner().get();
+  return message_loop_.task_runner().get();
+}
+
+ProfilingProcess* ProfilingGlobals::GetProfilingProcess() {
+  return &process_;
 }
 
 MemlogConnectionManager* ProfilingGlobals::GetMemlogConnectionManager() {
@@ -40,28 +37,13 @@
   return &backtrace_storage_;
 }
 
-scoped_refptr<base::SingleThreadTaskRunner> ProfilingGlobals::GetMainThread()
-    const {
-  CHECK(base::MessageLoop::current() == main_message_loop_);
-  return main_message_loop_->task_runner();
-}
-
 void ProfilingGlobals::RunMainMessageLoop() {
-  // TODO(brettw) if we never add anything interesting on the main thread here,
-  // we can change this so the main thread *is* the I/O thread. This will save
-  // some resources.
-  base::MessageLoopForUI message_loop;
-  DCHECK(!main_message_loop_);
-  main_message_loop_ = &message_loop;
-
   base::RunLoop run_loop;
   run_loop.Run();
-
-  main_message_loop_ = nullptr;
 }
 
 void ProfilingGlobals::QuitWhenIdle() {
-  main_message_loop_->QuitWhenIdle();
+  message_loop_.QuitWhenIdle();
 }
 
 }  // namespace profiling
diff --git a/chrome/profiling/profiling_globals.h b/chrome/profiling/profiling_globals.h
index 25970a8..23f0ed1 100644
--- a/chrome/profiling/profiling_globals.h
+++ b/chrome/profiling/profiling_globals.h
@@ -9,13 +9,12 @@
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "base/threading/thread.h"
+#include "base/message_loop/message_loop.h"
 #include "chrome/profiling/backtrace_storage.h"
 #include "chrome/profiling/memlog_connection_manager.h"
+#include "chrome/profiling/profiling_process.h"
 
 namespace base {
-class MessageLoopForUI;
-class SingleThreadTaskRunner;
 class TaskRunner;
 }  // namespace base
 
@@ -23,27 +22,26 @@
 
 class ProfilingGlobals {
  public:
-  static ProfilingGlobals* Get();
+  ProfilingGlobals();
+  ~ProfilingGlobals();
+
+  static inline ProfilingGlobals* Get() { return singleton_; }
 
   base::TaskRunner* GetIORunner();
+
+  ProfilingProcess* GetProfilingProcess();
   MemlogConnectionManager* GetMemlogConnectionManager();
   BacktraceStorage* GetBacktraceStorage();
 
-  // Returns non-null when inside RunMainMessageLoop. Call only on the
-  // main thread (otherwise there's a shutdown race).
-  scoped_refptr<base::SingleThreadTaskRunner> GetMainThread() const;
-
   void RunMainMessageLoop();
   void QuitWhenIdle();
 
  private:
-  ProfilingGlobals();
-  ~ProfilingGlobals();
+  static ProfilingGlobals* singleton_;
 
-  // Non-null inside RunMainMessageLoop.
-  base::MessageLoopForUI* main_message_loop_ = nullptr;
+  base::MessageLoopForIO message_loop_;
 
-  base::Thread io_thread_;
+  ProfilingProcess process_;
   MemlogConnectionManager memlog_connection_manager_;
   BacktraceStorage backtrace_storage_;
 
diff --git a/chrome/profiling/profiling_main.cc b/chrome/profiling/profiling_main.cc
index e549194..64027cb 100644
--- a/chrome/profiling/profiling_main.cc
+++ b/chrome/profiling/profiling_main.cc
@@ -7,9 +7,13 @@
 #include "base/command_line.h"
 #include "build/build_config.h"
 #include "chrome/common/chrome_switches.h"
+#include "chrome/common/profiling/profiling_constants.h"
 #include "chrome/profiling/profiling_globals.h"
+#include "chrome/profiling/profiling_process.h"
 #include "mojo/edk/embedder/embedder.h"
+#include "mojo/edk/embedder/incoming_broker_client_invitation.h"
 #include "mojo/edk/embedder/scoped_ipc_support.h"
+#include "mojo/edk/embedder/transport_protocol.h"
 
 #if defined(OS_WIN)
 #include "base/win/win_util.h"
@@ -18,17 +22,17 @@
 namespace profiling {
 
 int ProfilingMain(const base::CommandLine& cmdline) {
-  ProfilingGlobals* globals = ProfilingGlobals::Get();
+  ProfilingGlobals globals;
 
   mojo::edk::Init();
   mojo::edk::ScopedIPCSupport ipc_support(
-      globals->GetIORunner(),
+      globals.GetIORunner(),
       mojo::edk::ScopedIPCSupport::ShutdownPolicy::CLEAN);
 
   std::string pipe_id = cmdline.GetSwitchValueASCII(switches::kMemlogPipe);
-  globals->GetMemlogConnectionManager()->StartConnections(pipe_id);
+  globals.GetMemlogConnectionManager()->StartConnections(pipe_id);
 
-  ProfilingGlobals::Get()->RunMainMessageLoop();
+  globals.RunMainMessageLoop();
 
 #if defined(OS_WIN)
   base::win::SetShouldCrashOnProcessDetach(false);
diff --git a/chrome/profiling/profiling_process.cc b/chrome/profiling/profiling_process.cc
new file mode 100644
index 0000000..f9f81fd0
--- /dev/null
+++ b/chrome/profiling/profiling_process.cc
@@ -0,0 +1,33 @@
+// 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/profiling/profiling_process.h"
+
+#include "base/bind.h"
+#include "chrome/common/profiling/profiling_constants.h"
+#include "chrome/profiling/profiling_globals.h"
+
+namespace profiling {
+
+ProfilingProcess::ProfilingProcess() : binding_(this) {}
+
+ProfilingProcess::~ProfilingProcess() {}
+
+void ProfilingProcess::EnsureMojoStarted() {
+  if (started_mojo_)
+    return;
+  started_mojo_ = true;
+
+  control_invitation_ =
+      mojo::edk::IncomingBrokerClientInvitation::AcceptFromCommandLine(
+          mojo::edk::TransportProtocol::kLegacy);
+
+  binding_.Bind(mojom::ProfilingControlRequest(
+      control_invitation_->ExtractMessagePipe(kProfilingControlPipeName)));
+}
+
+void ProfilingProcess::AddNewSender(mojo::ScopedHandle sender_pipe,
+                                    int32_t sender_pid) {}
+
+}  // namespace profiling
diff --git a/chrome/profiling/profiling_process.h b/chrome/profiling/profiling_process.h
new file mode 100644
index 0000000..5030203
--- /dev/null
+++ b/chrome/profiling/profiling_process.h
@@ -0,0 +1,42 @@
+// 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_PROFILING_PROFILING_PROCESS_H_
+#define CHROME_PROFILING_PROFILING_PROCESS_H_
+
+#include "base/macros.h"
+#include "chrome/common/profiling/profiling_control.mojom.h"
+#include "mojo/edk/embedder/incoming_broker_client_invitation.h"
+#include "mojo/public/cpp/bindings/binding.h"
+
+namespace profiling {
+
+// Represents the profiling process side of the profiling <-> browser
+// connection. This class is not thread safe and must onle be called on the IO
+// thread (which is the main thread in the profiling process).
+class ProfilingProcess : public mojom::ProfilingControl {
+ public:
+  ProfilingProcess();
+  ~ProfilingProcess() override;
+
+  void EnsureMojoStarted();
+
+  // ProfilingControl implementation.
+  void AddNewSender(mojo::ScopedHandle sender_pipe,
+                    int32_t sender_pid) override;
+
+ private:
+  bool started_mojo_ = false;
+
+  std::unique_ptr<mojo::edk::IncomingBrokerClientInvitation>
+      control_invitation_;
+
+  mojo::Binding<mojom::ProfilingControl> binding_;
+
+  DISALLOW_COPY_AND_ASSIGN(ProfilingProcess);
+};
+
+}  // namespace profiling
+
+#endif  // CHROME_PROFILING_PROFILING_PROCESS_H_
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index dd3049c3..049d6dd1 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1445,6 +1445,7 @@
       "../browser/ssl/cert_verifier_browser_test.h",
       "../browser/ssl/certificate_reporting_test_utils.cc",
       "../browser/ssl/certificate_reporting_test_utils.h",
+      "../browser/ssl/chrome_expect_ct_reporter_browser_tests.cc",
       "../browser/ssl/chrome_ssl_host_state_delegate_test.cc",
       "../browser/ssl/security_state_tab_helper_browser_tests.cc",
       "../browser/ssl/ssl_browser_tests.cc",
@@ -3158,6 +3159,7 @@
     "../browser/metrics/chrome_browser_main_extra_parts_metrics_unittest.cc",
     "../browser/metrics/chrome_metrics_service_accessor_unittest.cc",
     "../browser/metrics/perf/perf_provider_chromeos_unittest.cc",
+    "../browser/metrics/process_memory_metrics_emitter_unittest.cc",
     "../browser/metrics/subprocess_metrics_provider_unittest.cc",
     "../browser/metrics/thread_watcher_android_unittest.cc",
     "../browser/metrics/thread_watcher_unittest.cc",
diff --git a/chrome/test/chromedriver/session_commands.cc b/chrome/test/chromedriver/session_commands.cc
index 62199ae..d98b28f 100644
--- a/chrome/test/chromedriver/session_commands.cc
+++ b/chrome/test/chromedriver/session_commands.cc
@@ -108,7 +108,9 @@
 
 namespace {
 
-std::unique_ptr<base::DictionaryValue> CreateCapabilities(Session* session) {
+std::unique_ptr<base::DictionaryValue> CreateCapabilities(
+    Session* session,
+    const Capabilities& capabilities) {
   std::unique_ptr<base::DictionaryValue> caps(new base::DictionaryValue());
   caps->SetString("browserName", "chrome");
   caps->SetString("version",
@@ -135,6 +137,13 @@
   caps->SetString("unexpectedAlertBehaviour",
                   session->unexpected_alert_behaviour);
 
+  // add setWindowRect based on whether we are desktop/android/remote
+  if (capabilities.IsAndroid() || capabilities.IsRemoteBrowser()) {
+    caps->SetBoolean("setWindowRect", false);
+  } else {
+    caps->SetBoolean("setWindowRect", true);
+  }
+
   ChromeDesktopImpl* desktop = NULL;
   Status status = session->chrome->GetAsDesktop(&desktop);
   if (status.IsOk()) {
@@ -239,16 +248,29 @@
                                                     session->w3c_compliant);
   if (status.IsError())
     return status;
-
   session->detach = capabilities.detach;
   session->force_devtools_screenshot = capabilities.force_devtools_screenshot;
-  session->capabilities = CreateCapabilities(session);
+  session->capabilities = CreateCapabilities(session, capabilities);
   value->reset(session->capabilities->DeepCopy());
   return CheckSessionCreated(session);
 }
 
 }  // namespace
 
+bool MatchCapabilities(base::DictionaryValue* capabilities) {
+  // attempt to match the capabilities requested to the actual capabilities
+  // reject if they don't match
+  if (capabilities->HasKey("browserName")) {
+    std::string name;
+    capabilities->GetString("browserName", &name);
+    if (name != "chrome") {
+      return false;
+    }
+  }
+
+  return true;
+}
+
 Status ExecuteInitSession(const InitSessionParams& bound_params,
                           Session* session,
                           const base::DictionaryValue& params,
diff --git a/chrome/test/chromedriver/session_commands.h b/chrome/test/chromedriver/session_commands.h
index 96d1fe0..072bb3a0 100644
--- a/chrome/test/chromedriver/session_commands.h
+++ b/chrome/test/chromedriver/session_commands.h
@@ -40,6 +40,8 @@
   PortManager* port_manager;
 };
 
+bool MatchCapabilities(base::DictionaryValue* capabilities);
+
 // Initializes a session.
 Status ExecuteInitSession(const InitSessionParams& bound_params,
                           Session* session,
diff --git a/chrome/test/chromedriver/session_commands_unittest.cc b/chrome/test/chromedriver/session_commands_unittest.cc
index 9c5312a..5170e201 100644
--- a/chrome/test/chromedriver/session_commands_unittest.cc
+++ b/chrome/test/chromedriver/session_commands_unittest.cc
@@ -60,6 +60,18 @@
 
 }  // namespace
 
+TEST(SessionCommandsTest, MatchCapabilities) {
+  base::DictionaryValue merged;
+  merged.SetString("browserName", "not chrome");
+
+  ASSERT_FALSE(MatchCapabilities(&merged));
+
+  merged.Clear();
+  merged.SetString("browserName", "chrome");
+
+  ASSERT_TRUE(MatchCapabilities(&merged));
+}
+
 TEST(SessionCommandsTest, Quit) {
   DetachChrome* chrome = new DetachChrome();
   Session session("id", std::unique_ptr<Chrome>(chrome));
diff --git a/chrome/test/data/webrtc/peerconnection_getstats.js b/chrome/test/data/webrtc/peerconnection_getstats.js
index b46cff2..a562ac4 100644
--- a/chrome/test/data/webrtc/peerconnection_getstats.js
+++ b/chrome/test/data/webrtc/peerconnection_getstats.js
@@ -136,6 +136,8 @@
   audioLevel: 'number',
   echoReturnLoss: 'number',
   echoReturnLossEnhancement: 'number',
+  totalAudioEnergy: 'number',
+  totalSamplesDuration: 'number'
 });
 gStatsWhitelist.set('track', kRTCMediaStreamTrackStats);
 
diff --git a/chrome/test/data/webui/extensions/cr_extensions_browsertest.js b/chrome/test/data/webui/extensions/cr_extensions_browsertest.js
index cfa72f43..47e1525d 100644
--- a/chrome/test/data/webui/extensions/cr_extensions_browsertest.js
+++ b/chrome/test/data/webui/extensions/cr_extensions_browsertest.js
@@ -194,6 +194,21 @@
       assert(extension_item_list_tests.TestNames.ItemListFiltering)).run();
 });
 
+TEST_F('CrExtensionsBrowserTest', 'ExtensionItemListEmpty', function() {
+  extension_item_list_tests.registerTests();
+  mocha.grep(assert(extension_item_list_tests.TestNames.ItemListNoItemsMsg))
+      .run();
+});
+
+TEST_F(
+    'CrExtensionsBrowserTest', 'ExtensionItemListNoSearchResults', function() {
+      extension_item_list_tests.registerTests();
+      mocha
+          .grep(assert(
+              extension_item_list_tests.TestNames.ItemListNoSearchResultsMsg))
+          .run();
+    });
+
 ////////////////////////////////////////////////////////////////////////////////
 // Extension Load Error Tests
 
diff --git a/chrome/test/data/webui/extensions/extension_item_list_test.js b/chrome/test/data/webui/extensions/extension_item_list_test.js
index c5b09be..56647c7a 100644
--- a/chrome/test/data/webui/extensions/extension_item_list_test.js
+++ b/chrome/test/data/webui/extensions/extension_item_list_test.js
@@ -7,12 +7,15 @@
   /** @enum {string} */
   var TestNames = {
     ItemListFiltering: 'item list filtering',
+    ItemListNoItemsMsg: 'empty item list',
+    ItemListNoSearchResultsMsg: 'empty item list filtering results',
   };
 
   function registerTests() {
     suite('ExtensionItemListTest', function() {
       /** @type {extensions.ItemList} */
       var itemList;
+      var testVisible;
 
       suiteSetup(function() {
         return PolymerTest.importHtml('chrome://extensions/item-list.html');
@@ -22,6 +25,8 @@
       setup(function() {
         PolymerTest.clearBody();
         itemList = new extensions.ItemList();
+        testVisible = extension_test_util.testVisible.bind(null, itemList);
+
         var createExt = extension_test_util.createExtensionInfo;
         var items =
             [createExt({name: 'Alpha', id: 'a'.repeat(32)}),
@@ -60,6 +65,24 @@
         itemList.filter = '';
         expectEquals(3, ironList.items.length);
       });
+
+      test(assert(TestNames.ItemListNoItemsMsg), function() {
+        testVisible('#no-items', false);
+        testVisible('#no-search-results', false);
+
+        itemList.items = [];
+        testVisible('#no-items', true);
+        testVisible('#no-search-results', false);
+      });
+
+      test(assert(TestNames.ItemListNoSearchResultsMsg), function() {
+        testVisible('#no-items', false);
+        testVisible('#no-search-results', false);
+
+        itemList.filter = 'non-existent name';
+        testVisible('#no-items', false);
+        testVisible('#no-search-results', true);
+      });
     });
   }
 
diff --git a/chrome/test/data/webui/extensions/extension_manager_test.js b/chrome/test/data/webui/extensions/extension_manager_test.js
index 4c3f760..14e4530 100644
--- a/chrome/test/data/webui/extensions/extension_manager_test.js
+++ b/chrome/test/data/webui/extensions/extension_manager_test.js
@@ -78,7 +78,6 @@
       });
 
       test(assert(TestNames.ItemListVisibility), function() {
-        var testVisible = extension_test_util.testVisible.bind(null, manager);
         var extension = getDataByName(manager.extensions, 'My extension 1');
 
         var listHasItemWithName = function(name) {
@@ -88,17 +87,14 @@
         };
 
         expectEquals(manager.extensions, manager.$['items-list'].items);
-        testVisible('#items-list', true);
         expectTrue(listHasItemWithName('My extension 1'));
 
         manager.removeItem(extension);
         Polymer.dom.flush();
-        testVisible('#items-list', false);
         expectFalse(listHasItemWithName('My extension 1'));
 
         manager.addItem(extension);
         Polymer.dom.flush();
-        testVisible('#items-list', true);
         expectTrue(listHasItemWithName('My extension 1'));
       });
 
diff --git a/chrome/test/data/webui/settings/easy_unlock_browsertest_chromeos.js b/chrome/test/data/webui/settings/easy_unlock_browsertest_chromeos.js
index dc0f9c0..ad86771 100644
--- a/chrome/test/data/webui/settings/easy_unlock_browsertest_chromeos.js
+++ b/chrome/test/data/webui/settings/easy_unlock_browsertest_chromeos.js
@@ -103,7 +103,6 @@
       // bots that do not have Bluetooth (don't actually support Easy Unlock).
       loadTimeData.overrideValues({
         easyUnlockAllowed: true,
-        easyUnlockProximityDetectionAllowed: false,
 
         easyUnlockSectionTitle: '',
         easyUnlockLearnMoreURL: '',
diff --git a/chrome/test/data/webui/settings/ensure_lazy_loaded.js b/chrome/test/data/webui/settings/ensure_lazy_loaded.js
index 7ec8a43..c108c52 100644
--- a/chrome/test/data/webui/settings/ensure_lazy_loaded.js
+++ b/chrome/test/data/webui/settings/ensure_lazy_loaded.js
@@ -5,6 +5,8 @@
 cr.define('settings', function() {
   function ensureLazyLoaded() {
     // Only trigger lazy loading, if we are in top-level Settings page.
+    // IMPORTANT: This is used when running tests that use the Polymer Bundler
+    // (aka vulcanize).
     if (location.href == location.origin + '/') {
       suiteSetup(function() {
         return new Promise(function(resolve, reject) {
diff --git a/chromeos/components/tether/BUILD.gn b/chromeos/components/tether/BUILD.gn
index fd5cc912..aff8e36 100644
--- a/chromeos/components/tether/BUILD.gn
+++ b/chromeos/components/tether/BUILD.gn
@@ -30,8 +30,9 @@
     "disconnect_tethering_operation.h",
     "host_connection_metrics_logger.cc",
     "host_connection_metrics_logger.h",
-    "host_scan_cache.cc",
     "host_scan_cache.h",
+    "host_scan_cache_entry.cc",
+    "host_scan_cache_entry.h",
     "host_scan_device_prioritizer.h",
     "host_scan_device_prioritizer_impl.cc",
     "host_scan_device_prioritizer_impl.h",
@@ -47,6 +48,8 @@
     "keep_alive_operation.h",
     "keep_alive_scheduler.cc",
     "keep_alive_scheduler.h",
+    "master_host_scan_cache.cc",
+    "master_host_scan_cache.h",
     "message_transfer_operation.cc",
     "message_transfer_operation.h",
     "message_wrapper.cc",
@@ -60,8 +63,9 @@
     "pref_names.h",
     "tether_connector.cc",
     "tether_connector.h",
-    "tether_disconnector.cc",
     "tether_disconnector.h",
+    "tether_disconnector_impl.cc",
+    "tether_disconnector_impl.h",
     "tether_host_fetcher.cc",
     "tether_host_fetcher.h",
     "tether_host_response_recorder.cc",
@@ -146,7 +150,6 @@
     "device_status_util_unittest.cc",
     "disconnect_tethering_operation_unittest.cc",
     "host_connection_metrics_logger_unittest.cc",
-    "host_scan_cache_unittest.cc",
     "host_scan_device_prioritizer_impl_unittest.cc",
     "host_scan_scheduler_unittest.cc",
     "host_scanner_operation_unittest.cc",
@@ -154,12 +157,13 @@
     "initializer_unittest.cc",
     "keep_alive_operation_unittest.cc",
     "keep_alive_scheduler_unittest.cc",
+    "master_host_scan_cache_unittest.cc",
     "message_transfer_operation_unittest.cc",
     "message_wrapper_unittest.cc",
     "network_configuration_remover_unittest.cc",
     "network_connection_handler_tether_delegate_unittest.cc",
     "tether_connector_unittest.cc",
-    "tether_disconnector_unittest.cc",
+    "tether_disconnector_impl_unittest.cc",
     "tether_host_fetcher_unittest.cc",
     "tether_host_response_recorder_unittest.cc",
     "tether_network_disconnection_handler_unittest.cc",
diff --git a/chromeos/components/tether/fake_host_scan_cache.cc b/chromeos/components/tether/fake_host_scan_cache.cc
index fae2ff6..4af9eda6 100644
--- a/chromeos/components/tether/fake_host_scan_cache.cc
+++ b/chromeos/components/tether/fake_host_scan_cache.cc
@@ -4,40 +4,15 @@
 
 #include "chromeos/components/tether/fake_host_scan_cache.h"
 
-#include "chromeos/components/tether/tether_host_response_recorder.h"
-
 namespace chromeos {
 
 namespace tether {
 
-namespace {
-
-// Shared among all FakeHostScanCache instances. This pointer is not used for
-// anything, but HostScanCache's constructor calls AddObserver() on the
-// TetherHostResponseRecorder* passed to its constructor, so a valid object must
-// be passed to the constructor to prevent a segfault.
-TetherHostResponseRecorder* kTetherHostResponseRecorder = nullptr;
-
-TetherHostResponseRecorder* GetTetherHostResponseRecorder() {
-  if (kTetherHostResponseRecorder)
-    return kTetherHostResponseRecorder;
-
-  kTetherHostResponseRecorder =
-      new TetherHostResponseRecorder(nullptr /* pref_service */);
-  return kTetherHostResponseRecorder;
-}
-
-}  // namespace
-
-FakeHostScanCache::FakeHostScanCache()
-    : HostScanCache(nullptr /* network_state_handler */,
-                    nullptr /* active_host */,
-                    GetTetherHostResponseRecorder(),
-                    nullptr /* device_id_tether_network_guid_map */) {}
+FakeHostScanCache::FakeHostScanCache() : HostScanCache() {}
 
 FakeHostScanCache::~FakeHostScanCache() {}
 
-const FakeHostScanCache::CacheEntry* FakeHostScanCache::GetCacheEntry(
+const HostScanCacheEntry* FakeHostScanCache::GetCacheEntry(
     const std::string& tether_network_guid) {
   auto it = cache_.find(tether_network_guid);
   if (it == cache_.end())
@@ -46,28 +21,13 @@
   return &it->second;
 }
 
-void FakeHostScanCache::SetHostScanResult(
-    const std::string& tether_network_guid,
-    const std::string& device_name,
-    const std::string& carrier,
-    int battery_percentage,
-    int signal_strength,
-    bool setup_required) {
-  auto it = cache_.find(tether_network_guid);
-  if (it != cache_.end()) {
-    // If already in the cache, update the cache with new values.
-    it->second.device_name = device_name;
-    it->second.carrier = carrier;
-    it->second.battery_percentage = battery_percentage;
-    it->second.signal_strength = signal_strength;
-    it->second.setup_required = setup_required;
-    return;
-  }
+void FakeHostScanCache::SetHostScanResult(const HostScanCacheEntry& entry) {
+  // Erase any existing entry with the same GUID if it exists (if nothing
+  // currently exists with that GUID, this is a no-op).
+  cache_.erase(entry.tether_network_guid);
 
-  // Otherwise, add a new entry.
-  cache_.emplace(tether_network_guid,
-                 CacheEntry{device_name, carrier, battery_percentage,
-                            signal_strength, setup_required});
+  // Add the new entry.
+  cache_.emplace(entry.tether_network_guid, entry);
 }
 
 bool FakeHostScanCache::RemoveHostScanResult(
@@ -97,8 +57,6 @@
   return false;
 }
 
-void FakeHostScanCache::OnPreviouslyConnectedHostIdsChanged() {}
-
 }  // namespace tether
 
 }  // namespace chromeos
diff --git a/chromeos/components/tether/fake_host_scan_cache.h b/chromeos/components/tether/fake_host_scan_cache.h
index e63c3fb8..024bdaf 100644
--- a/chromeos/components/tether/fake_host_scan_cache.h
+++ b/chromeos/components/tether/fake_host_scan_cache.h
@@ -18,14 +18,6 @@
 // Test double for HostScanCache which stores cache results in memory.
 class FakeHostScanCache : public HostScanCache {
  public:
-  struct CacheEntry {
-    std::string device_name;
-    std::string carrier;
-    int battery_percentage;
-    int signal_strength;
-    bool setup_required;
-  };
-
   FakeHostScanCache();
   ~FakeHostScanCache() override;
 
@@ -40,29 +32,23 @@
   }
 
   // Getters for contents of the cache.
-  const FakeHostScanCache::CacheEntry* GetCacheEntry(
+  const HostScanCacheEntry* GetCacheEntry(
       const std::string& tether_network_guid);
   size_t size() { return cache_.size(); }
   bool empty() { return cache_.empty(); }
-  const std::unordered_map<std::string, FakeHostScanCache::CacheEntry> cache() {
+  const std::unordered_map<std::string, HostScanCacheEntry> cache() {
     return cache_;
   }
 
   // HostScanCache:
-  void SetHostScanResult(const std::string& tether_network_guid,
-                         const std::string& device_name,
-                         const std::string& carrier,
-                         int battery_percentage,
-                         int signal_strength,
-                         bool setup_required) override;
+  void SetHostScanResult(const HostScanCacheEntry& entry) override;
   bool RemoveHostScanResult(const std::string& tether_network_guid) override;
   void ClearCacheExceptForActiveHost() override;
   bool DoesHostRequireSetup(const std::string& tether_network_guid) override;
-  void OnPreviouslyConnectedHostIdsChanged() override;
 
  private:
   std::string active_host_tether_network_guid_;
-  std::unordered_map<std::string, CacheEntry> cache_;
+  std::unordered_map<std::string, HostScanCacheEntry> cache_;
 
   DISALLOW_COPY_AND_ASSIGN(FakeHostScanCache);
 };
diff --git a/chromeos/components/tether/fake_tether_host_fetcher.h b/chromeos/components/tether/fake_tether_host_fetcher.h
index a75c9905..7a6e93e1 100644
--- a/chromeos/components/tether/fake_tether_host_fetcher.h
+++ b/chromeos/components/tether/fake_tether_host_fetcher.h
@@ -20,12 +20,17 @@
  public:
   FakeTetherHostFetcher(std::vector<cryptauth::RemoteDevice> tether_hosts,
                         bool synchronously_reply_with_results);
-  FakeTetherHostFetcher(bool synchronously_reply_with_results);
+  explicit FakeTetherHostFetcher(bool synchronously_reply_with_results);
   ~FakeTetherHostFetcher() override;
 
+  void set_synchronously_reply_with_results(
+      bool synchronously_reply_with_results) {
+    synchronously_reply_with_results_ = synchronously_reply_with_results;
+  }
+
   void SetTetherHosts(const std::vector<cryptauth::RemoteDevice> tether_hosts);
 
-  // If |sychronously_reply_with_results| is false, calling this method will
+  // If |synchronously_reply_with_results_| is false, calling this method will
   // actually invoke the callbacks.
   void InvokePendingCallbacks();
 
diff --git a/chromeos/components/tether/host_scan_cache.cc b/chromeos/components/tether/host_scan_cache.cc
deleted file mode 100644
index 51696431..0000000
--- a/chromeos/components/tether/host_scan_cache.cc
+++ /dev/null
@@ -1,226 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromeos/components/tether/host_scan_cache.h"
-
-#include <algorithm>
-
-#include "base/bind.h"
-#include "base/memory/ptr_util.h"
-#include "chromeos/components/tether/active_host.h"
-#include "chromeos/components/tether/device_id_tether_network_guid_map.h"
-#include "chromeos/components/tether/tether_host_response_recorder.h"
-#include "chromeos/components/tether/timer_factory.h"
-#include "chromeos/network/network_state_handler.h"
-#include "components/proximity_auth/logging/logging.h"
-
-namespace chromeos {
-
-namespace tether {
-
-HostScanCache::HostScanCache(
-    NetworkStateHandler* network_state_handler,
-    ActiveHost* active_host,
-    TetherHostResponseRecorder* tether_host_response_recorder,
-    DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map)
-    : timer_factory_(base::MakeUnique<TimerFactory>()),
-      network_state_handler_(network_state_handler),
-      active_host_(active_host),
-      tether_host_response_recorder_(tether_host_response_recorder),
-      device_id_tether_network_guid_map_(device_id_tether_network_guid_map),
-      weak_ptr_factory_(this) {
-  tether_host_response_recorder_->AddObserver(this);
-}
-
-HostScanCache::~HostScanCache() {
-  tether_host_response_recorder_->RemoveObserver(this);
-}
-
-void HostScanCache::SetHostScanResult(const std::string& tether_network_guid,
-                                      const std::string& device_name,
-                                      const std::string& carrier,
-                                      int battery_percentage,
-                                      int signal_strength,
-                                      bool setup_required) {
-  DCHECK(!tether_network_guid.empty());
-
-  auto found_iter = tether_guid_to_timer_map_.find(tether_network_guid);
-
-  if (found_iter == tether_guid_to_timer_map_.end()) {
-    // Add the Tether network to NetworkStateHandler and create an associated
-    // Timer.
-    network_state_handler_->AddTetherNetworkState(
-        tether_network_guid, device_name, carrier, battery_percentage,
-        signal_strength, HasConnectedToHost(tether_network_guid));
-    tether_guid_to_timer_map_.emplace(tether_network_guid,
-                                      timer_factory_->CreateOneShotTimer());
-
-    PA_LOG(INFO) << "Added scan result for Tether network with GUID "
-                 << tether_network_guid << ". Device name: " << device_name
-                 << ", carrier: " << carrier
-                 << ", battery percentage: " << battery_percentage
-                 << ", signal strength: " << signal_strength;
-  } else {
-    // Update the existing network and stop the associated Timer.
-    network_state_handler_->UpdateTetherNetworkProperties(
-        tether_network_guid, carrier, battery_percentage, signal_strength);
-    found_iter->second->Stop();
-
-    PA_LOG(INFO) << "Updated scan result for Tether network with GUID "
-                 << tether_network_guid << ". New carrier: " << carrier << ", "
-                 << "new battery percentage: " << battery_percentage << ", "
-                 << "new signal strength: " << signal_strength;
-  }
-
-  if (setup_required)
-    setup_required_tether_guids_.insert(tether_network_guid);
-  else
-    setup_required_tether_guids_.erase(tether_network_guid);
-
-  StartTimer(tether_network_guid);
-}
-
-bool HostScanCache::RemoveHostScanResult(
-    const std::string& tether_network_guid) {
-  DCHECK(!tether_network_guid.empty());
-
-  auto it = tether_guid_to_timer_map_.find(tether_network_guid);
-  if (it == tether_guid_to_timer_map_.end()) {
-    PA_LOG(ERROR) << "Attempted to remove a host scan result which does not "
-                  << "exist in the cache. GUID: " << tether_network_guid;
-    return false;
-  }
-
-  if (active_host_->GetTetherNetworkGuid() == tether_network_guid) {
-    PA_LOG(ERROR) << "RemoveHostScanResult() called for Tether network with "
-                  << "GUID " << tether_network_guid << ", but the "
-                  << "corresponding device is the active host. Not removing "
-                  << "this scan result from the cache.";
-    return false;
-  }
-
-  tether_guid_to_timer_map_.erase(it);
-  setup_required_tether_guids_.erase(tether_network_guid);
-  return network_state_handler_->RemoveTetherNetworkState(tether_network_guid);
-}
-
-void HostScanCache::ClearCacheExceptForActiveHost() {
-  // Create a list of all Tether network GUIDs serving as keys to
-  // |tether_guid_to_timer_map_|.
-  std::vector<std::string> tether_network_guids;
-  tether_network_guids.reserve(tether_guid_to_timer_map_.size());
-  for (auto& it : tether_guid_to_timer_map_)
-    tether_network_guids.push_back(it.first);
-
-  std::string active_host_tether_guid = active_host_->GetTetherNetworkGuid();
-  if (active_host_tether_guid.empty()) {
-    PA_LOG(INFO) << "Clearing all " << tether_guid_to_timer_map_.size() << " "
-                 << "entries from the cache.";
-  } else {
-    PA_LOG(INFO) << "Clearing " << (tether_guid_to_timer_map_.size() - 1) << " "
-                 << "of the " << tether_guid_to_timer_map_.size() << " "
-                 << "entries from the cache. Not removing the entry "
-                 << "corresponding to the Tether network with GUID "
-                 << active_host_tether_guid << " because it represents the "
-                 << "active host.";
-  }
-
-  // Iterate through the keys, removing all scan results not corresponding to
-  // the active host. Iteration is done via a list of pre-computed keys instead
-  // if iterating through the map because RemoteHostScanResult() will remove
-  // key/value pairs from the map, which would invalidate the map iterator.
-  for (auto& tether_network_guid : tether_network_guids) {
-    if (active_host_->GetTetherNetworkGuid() == tether_network_guid) {
-      // Do not remove the active host from the cache.
-      continue;
-    }
-
-    RemoveHostScanResult(tether_network_guid);
-  }
-}
-
-bool HostScanCache::DoesHostRequireSetup(
-    const std::string& tether_network_guid) {
-  return setup_required_tether_guids_.find(tether_network_guid) !=
-         setup_required_tether_guids_.end();
-}
-
-void HostScanCache::OnPreviouslyConnectedHostIdsChanged() {
-  for (auto& map_entry : tether_guid_to_timer_map_) {
-    const std::string& tether_network_guid = map_entry.first;
-    if (!HasConnectedToHost(tether_network_guid))
-      continue;
-
-    // If a the current device has connected to the Tether network with GUID
-    // |tether_network_guid|, alert |network_state_handler_|. Note that this
-    // function is a no-op if it is called on a network which already has its
-    // HasConnectedToHost property set to true.
-    bool update_successful =
-        network_state_handler_->SetTetherNetworkHasConnectedToHost(
-            tether_network_guid);
-
-    if (update_successful) {
-      PA_LOG(INFO) << "Successfully set the HasConnectedToHost property of "
-                   << "the Tether network with GUID " << tether_network_guid
-                   << " to true.";
-    }
-  }
-}
-
-void HostScanCache::SetTimerFactoryForTest(
-    std::unique_ptr<TimerFactory> timer_factory_for_test) {
-  timer_factory_ = std::move(timer_factory_for_test);
-}
-
-bool HostScanCache::HasConnectedToHost(const std::string& tether_network_guid) {
-  std::string device_id =
-      device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid(
-          tether_network_guid);
-  std::vector<std::string> connected_device_ids =
-      tether_host_response_recorder_->GetPreviouslyConnectedHostIds();
-  return std::find(connected_device_ids.begin(), connected_device_ids.end(),
-                   device_id) != connected_device_ids.end();
-}
-
-void HostScanCache::StartTimer(const std::string& tether_network_guid) {
-  auto found_iter = tether_guid_to_timer_map_.find(tether_network_guid);
-  DCHECK(found_iter != tether_guid_to_timer_map_.end());
-  DCHECK(!found_iter->second->IsRunning());
-
-  PA_LOG(INFO) << "Starting host scan cache timer for Tether network with GUID "
-               << tether_network_guid << ". Will fire in "
-               << kNumMinutesBeforeCacheEntryExpires << " minutes.";
-
-  found_iter->second->Start(
-      FROM_HERE,
-      base::TimeDelta::FromMinutes(kNumMinutesBeforeCacheEntryExpires),
-      base::Bind(&HostScanCache::OnTimerFired, weak_ptr_factory_.GetWeakPtr(),
-                 tether_network_guid));
-}
-
-void HostScanCache::OnTimerFired(const std::string& tether_network_guid) {
-  if (active_host_->GetTetherNetworkGuid() == tether_network_guid) {
-    // Log as a warning. This situation should be uncommon in practice since
-    // KeepAliveScheduler should schedule a new keep-alive status update every
-    // 4 minutes.
-    PA_LOG(WARNING) << "Timer fired for Tether network GUID "
-                    << tether_network_guid << ", but the corresponding device "
-                    << "is the active host. Restarting timer.";
-
-    // If the Timer which fired corresponds to the active host, do not remove
-    // the cache entry. The active host must always remain in the cache so that
-    // the UI can reflect that it is the connecting/connected network. In this
-    // case, just restart the timer.
-    StartTimer(tether_network_guid);
-    return;
-  }
-
-  PA_LOG(INFO) << "Timer fired for Tether network GUID " << tether_network_guid
-               << ". Removing stale scan result.";
-  RemoveHostScanResult(tether_network_guid);
-}
-
-}  // namespace tether
-
-}  // namespace chromeos
diff --git a/chromeos/components/tether/host_scan_cache.h b/chromeos/components/tether/host_scan_cache.h
index 762f3ef..295f291 100644
--- a/chromeos/components/tether/host_scan_cache.h
+++ b/chromeos/components/tether/host_scan_cache.h
@@ -5,111 +5,46 @@
 #ifndef CHROMEOS_COMPONENTS_TETHER_HOST_SCAN_CACHE_H_
 #define CHROMEOS_COMPONENTS_TETHER_HOST_SCAN_CACHE_H_
 
-#include <memory>
-#include <unordered_map>
-
 #include "base/macros.h"
-#include "base/memory/weak_ptr.h"
-#include "base/timer/timer.h"
-#include "chromeos/components/tether/tether_host_response_recorder.h"
+#include "chromeos/components/tether/host_scan_cache_entry.h"
 
 namespace chromeos {
 
-class NetworkStateHandler;
-
 namespace tether {
 
-class ActiveHost;
-class DeviceIdTetherNetworkGuidMap;
-class TetherHostResponseRecorder;
-class TimerFactory;
-
-// Caches scan results and inserts them into the network stack.
-class HostScanCache : public TetherHostResponseRecorder::Observer {
+// Caches host scan results.
+class HostScanCache {
  public:
-  // The number of minutes that a cache entry is considered to be valid before
-  // it becomes stale. Once a cache entry is inserted, it will be automatically
-  // removed after this amount of time passes unless it corresponds to the
-  // active host. This value was chosen for two reasons:
-  //     (1) Tether properties such as battery percentage and signal strength
-  //         are ephemeral in nature, so keeping these values cached for more
-  //         than a short period makes it likely that the values will be wrong.
-  //     (2) Tether networks rely on proximity to a tether host device, so it is
-  //         possible that host devices have physically moved away from each
-  //         other. We assume that the devices do not stay in proximity to one
-  //         another until a new scan result is received which proves that they
-  //         are still within the distance needed to communicate.
-  static constexpr int kNumMinutesBeforeCacheEntryExpires = 5;
-
-  HostScanCache(
-      NetworkStateHandler* network_state_handler,
-      ActiveHost* active_host,
-      TetherHostResponseRecorder* tether_host_response_recorder,
-      DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map);
-  virtual ~HostScanCache();
+  HostScanCache() {}
+  virtual ~HostScanCache() {}
 
   // Updates the cache to include this scan result. If no scan result for
   // |tether_network_guid| exists in the cache, a scan result will be added;
   // if a scan result is already present, it is updated with the new data
-  // provided as parameters to this function. Once scan results have been
-  // updated, a timer starts counting down |kNumMinutesBeforeCacheEntryExpires|
-  // minutes. Once the timer fires, the scan result is automatically removed
-  // from the cache unless it corresponds to the active host.
-  // Note: |signal_strength| should be in the range [0, 100]. This is different
-  // from the |connection_strength| field received in ConnectTetheringResponse
-  // and KeepAliveTickleResponse messages (the range is [0, 4] in those cases).
-  // |battery_percentage| should also be in the range [0, 100].
-  // |setup_required| indicates that the host device requires first-time setup,
-  // i.e., user interaction to allow tethering.
-  virtual void SetHostScanResult(const std::string& tether_network_guid,
-                                 const std::string& device_name,
-                                 const std::string& carrier,
-                                 int battery_percentage,
-                                 int signal_strength,
-                                 bool setup_required);
+  // provided as parameters to this function.
+  virtual void SetHostScanResult(const HostScanCacheEntry& entry) = 0;
 
   // Removes the scan result with GUID |tether_network_guid| from the cache. If
-  // no cache result with that GUID was present in the cache, this function is
+  // no scan result with that GUID was present in the cache, this function is
   // a no-op. Returns whether a scan result was actually removed.
-  virtual bool RemoveHostScanResult(const std::string& tether_network_guid);
+  virtual bool RemoveHostScanResult(const std::string& tether_network_guid) = 0;
 
   // Removes all scan results from the cache unless they correspond to the
   // active host; the active host must always remain in the cache while
   // connecting/connected to ensure the UI is up to date.
-  virtual void ClearCacheExceptForActiveHost();
+  // TODO(khorimoto): Remove this function. Currently, scan results are cleared
+  // when a new scan starts and are filled back in as the scan completes. This
+  // allows for a situation to occur where the UI removes a network then adds
+  // it back at some time later, which is undesirable as a user. Instead,
+  // existing scan results should remain in the cache until a scan concludes and
+  // no updated scan results for those existing results exist.
+  virtual void ClearCacheExceptForActiveHost() = 0;
 
-  // Returns true if the host device requires first-time setup, i.e., user
-  // interaction to allow tethering.
-  virtual bool DoesHostRequireSetup(const std::string& tether_network_guid);
-
-  // TetherHostResponseRecorder::Observer:
-  void OnPreviouslyConnectedHostIdsChanged() override;
+  // Returns whether the scan result corresponding to |tether_network_guid|
+  // requires first-time setup (i.e., user interaction) to allow tethering.
+  virtual bool DoesHostRequireSetup(const std::string& tether_network_guid) = 0;
 
  private:
-  friend class HostScanCacheTest;
-
-  void SetTimerFactoryForTest(
-      std::unique_ptr<TimerFactory> timer_factory_for_test);
-
-  bool HasConnectedToHost(const std::string& tether_network_guid);
-  void StartTimer(const std::string& tether_network_guid);
-  void OnTimerFired(const std::string& tether_network_guid);
-
-  std::unique_ptr<TimerFactory> timer_factory_;
-  NetworkStateHandler* network_state_handler_;
-  ActiveHost* active_host_;
-  TetherHostResponseRecorder* tether_host_response_recorder_;
-  DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map_;
-
-  // Maps from the Tether network GUID to a Timer object. While a scan result is
-  // active in the cache, the corresponding Timer object starts running; if the
-  // timer fires, the result is removed (unless it corresponds to the active
-  // host).
-  std::unordered_map<std::string, std::unique_ptr<base::Timer>>
-      tether_guid_to_timer_map_;
-  std::unordered_set<std::string> setup_required_tether_guids_;
-  base::WeakPtrFactory<HostScanCache> weak_ptr_factory_;
-
   DISALLOW_COPY_AND_ASSIGN(HostScanCache);
 };
 
diff --git a/chromeos/components/tether/host_scan_cache_entry.cc b/chromeos/components/tether/host_scan_cache_entry.cc
new file mode 100644
index 0000000..10ceb06e
--- /dev/null
+++ b/chromeos/components/tether/host_scan_cache_entry.cc
@@ -0,0 +1,86 @@
+// 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 "chromeos/components/tether/host_scan_cache_entry.h"
+
+#include "base/memory/ptr_util.h"
+
+namespace chromeos {
+
+namespace tether {
+
+HostScanCacheEntry::Builder::Builder() {}
+
+HostScanCacheEntry::Builder::~Builder() {}
+
+std::unique_ptr<HostScanCacheEntry> HostScanCacheEntry::Builder::Build() {
+  DCHECK(!tether_network_guid_.empty());
+
+  return base::WrapUnique(new HostScanCacheEntry(
+      tether_network_guid_, device_name_, carrier_, battery_percentage_,
+      signal_strength_, setup_required_));
+}
+
+HostScanCacheEntry::Builder& HostScanCacheEntry::Builder::SetTetherNetworkGuid(
+    const std::string& tether_network_guid) {
+  tether_network_guid_ = tether_network_guid;
+  return *this;
+}
+
+HostScanCacheEntry::Builder& HostScanCacheEntry::Builder::SetDeviceName(
+    const std::string& device_name) {
+  device_name_ = device_name;
+  return *this;
+}
+
+HostScanCacheEntry::Builder& HostScanCacheEntry::Builder::SetCarrier(
+    const std::string& carrier) {
+  carrier_ = carrier;
+  return *this;
+}
+
+HostScanCacheEntry::Builder& HostScanCacheEntry::Builder::SetBatteryPercentage(
+    int battery_percentage) {
+  battery_percentage_ = battery_percentage;
+  return *this;
+}
+
+HostScanCacheEntry::Builder& HostScanCacheEntry::Builder::SetSignalStrength(
+    int signal_strength) {
+  signal_strength_ = signal_strength;
+  return *this;
+}
+
+HostScanCacheEntry::Builder& HostScanCacheEntry::Builder::SetSetupRequired(
+    bool setup_required) {
+  setup_required_ = setup_required;
+  return *this;
+}
+
+HostScanCacheEntry::HostScanCacheEntry(const std::string& tether_network_guid,
+                                       const std::string& device_name,
+                                       const std::string& carrier,
+                                       int battery_percentage,
+                                       int signal_strength,
+                                       bool setup_required)
+    : tether_network_guid(tether_network_guid),
+      device_name(device_name),
+      carrier(carrier),
+      battery_percentage(battery_percentage),
+      signal_strength(signal_strength),
+      setup_required(setup_required) {}
+
+HostScanCacheEntry::HostScanCacheEntry(const HostScanCacheEntry& other)
+    : tether_network_guid(other.tether_network_guid),
+      device_name(other.device_name),
+      carrier(other.carrier),
+      battery_percentage(other.battery_percentage),
+      signal_strength(other.signal_strength),
+      setup_required(other.setup_required) {}
+
+HostScanCacheEntry::~HostScanCacheEntry() {}
+
+}  // namespace tether
+
+}  // namespace chromeos
diff --git a/chromeos/components/tether/host_scan_cache_entry.h b/chromeos/components/tether/host_scan_cache_entry.h
new file mode 100644
index 0000000..150e512
--- /dev/null
+++ b/chromeos/components/tether/host_scan_cache_entry.h
@@ -0,0 +1,80 @@
+// 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 CHROMEOS_COMPONENTS_TETHER_HOST_SCAN_CACHE_ENTRY_H_
+#define CHROMEOS_COMPONENTS_TETHER_HOST_SCAN_CACHE_ENTRY_H_
+
+#include <memory>
+#include <string>
+
+#include "base/logging.h"
+
+namespace chromeos {
+
+namespace tether {
+
+// Entry to place within a HostScanCache. Contains metadata about a Tether host
+// which has been scanned.
+class HostScanCacheEntry {
+ public:
+  class Builder {
+   public:
+    Builder();
+    virtual ~Builder();
+
+    std::unique_ptr<HostScanCacheEntry> Build();
+    Builder& SetTetherNetworkGuid(const std::string& tether_network_guid);
+    Builder& SetDeviceName(const std::string& device_name);
+    Builder& SetCarrier(const std::string& carrier);
+    Builder& SetBatteryPercentage(int battery_percentage);
+    Builder& SetSignalStrength(int signal_strength);
+    Builder& SetSetupRequired(bool setup_required);
+
+   private:
+    std::string tether_network_guid_;
+    std::string device_name_;
+    std::string carrier_;
+    int battery_percentage_ = 100;
+    int signal_strength_ = 100;
+    bool setup_required_ = false;
+  };
+
+  HostScanCacheEntry(const HostScanCacheEntry& other);
+  virtual ~HostScanCacheEntry();
+
+  // GUID corresponding to the scanned device.
+  const std::string tether_network_guid;
+
+  // Human-readable name of the device.
+  const std::string device_name;
+
+  // Human-readable name of the cellular carrier.
+  const std::string carrier;
+
+  // Percentage from 0 to 100 (inclusive).
+  const int battery_percentage;
+
+  // Signal strength from 0 to 100 (inclusive). Note that this is different from
+  // the "connection strength" value that is sent over the Tether protocol,
+  // which ranges from 0 to 4 (see ConnectTetheringResponse).
+  const int signal_strength;
+
+  // Whether the scanned host requires first-time setup before use (i.e.,
+  // whether the user must interact with UI on the phone to initiate tethering).
+  const bool setup_required;
+
+ protected:
+  HostScanCacheEntry(const std::string& tether_network_guid,
+                     const std::string& device_name,
+                     const std::string& carrier,
+                     int battery_percentage,
+                     int signal_strength,
+                     bool setup_required);
+};
+
+}  // namespace tether
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_COMPONENTS_TETHER_HOST_SCAN_CACHE_ENTRY_H_
diff --git a/chromeos/components/tether/host_scan_cache_unittest.cc b/chromeos/components/tether/host_scan_cache_unittest.cc
deleted file mode 100644
index ae09f5e..0000000
--- a/chromeos/components/tether/host_scan_cache_unittest.cc
+++ /dev/null
@@ -1,463 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromeos/components/tether/host_scan_cache.h"
-
-#include <memory>
-#include <unordered_map>
-#include <vector>
-
-#include "base/callback.h"
-#include "base/memory/ptr_util.h"
-#include "base/test/scoped_task_environment.h"
-#include "base/timer/mock_timer.h"
-#include "chromeos/components/tether/device_id_tether_network_guid_map.h"
-#include "chromeos/components/tether/fake_active_host.h"
-#include "chromeos/components/tether/fake_host_scan_cache.h"
-#include "chromeos/components/tether/mock_tether_host_response_recorder.h"
-#include "chromeos/components/tether/timer_factory.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/network/network_state.h"
-#include "chromeos/network/network_state_handler.h"
-#include "chromeos/network/network_state_test.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using testing::NiceMock;
-using testing::Invoke;
-
-namespace chromeos {
-
-namespace tether {
-
-namespace {
-
-const char kTetherGuid0[] = "kTetherGuid0";
-const char kTetherGuid1[] = "kTetherGuid1";
-const char kTetherGuid2[] = "kTetherGuid2";
-const char kTetherGuid3[] = "kTetherGuid3";
-
-const char kTetherDeviceName0[] = "kDeviceName1";
-const char kTetherDeviceName1[] = "kDeviceName2";
-const char kTetherDeviceName2[] = "kDeviceName3";
-const char kTetherDeviceName3[] = "kDeviceName4";
-
-const char kTetherCarrier0[] = "kTetherCarrier0";
-const char kTetherCarrier1[] = "kTetherCarrier1";
-const char kTetherCarrier2[] = "kTetherCarrier2";
-const char kTetherCarrier3[] = "kTetherCarrier3";
-
-const int kTetherBatteryPercentage0 = 20;
-const int kTetherBatteryPercentage1 = 40;
-const int kTetherBatteryPercentage2 = 60;
-const int kTetherBatteryPercentage3 = 80;
-
-const int kTetherSignalStrength0 = 25;
-const int kTetherSignalStrength1 = 50;
-const int kTetherSignalStrength2 = 75;
-const int kTetherSignalStrength3 = 100;
-
-const bool kTetherSetupRequired0 = true;
-const bool kTetherSetupRequired1 = false;
-const bool kTetherSetupRequired2 = true;
-const bool kTetherSetupRequired3 = false;
-
-// MockTimer which invokes a callback in its destructor.
-class ExtendedMockTimer : public base::MockTimer {
- public:
-  explicit ExtendedMockTimer(const base::Closure& destructor_callback)
-      : base::MockTimer(true /* retain_user_task */, false /* is_repeating */),
-        destructor_callback_(destructor_callback) {}
-
-  ~ExtendedMockTimer() override { destructor_callback_.Run(); }
-
- private:
-  base::Closure destructor_callback_;
-};
-
-class TestTimerFactory : public TimerFactory {
- public:
-  TestTimerFactory() {}
-  ~TestTimerFactory() override {}
-
-  std::unordered_map<std::string, ExtendedMockTimer*>&
-  tether_network_guid_to_timer_map() {
-    return tether_network_guid_to_timer_map_;
-  }
-
-  void set_tether_network_guid_for_next_timer(
-      const std::string& tether_network_guid_for_next_timer) {
-    tether_network_guid_for_next_timer_ = tether_network_guid_for_next_timer;
-  }
-
-  // TimerFactory:
-  std::unique_ptr<base::Timer> CreateOneShotTimer() override {
-    EXPECT_FALSE(tether_network_guid_for_next_timer_.empty());
-    ExtendedMockTimer* mock_timer = new ExtendedMockTimer(base::Bind(
-        &TestTimerFactory::OnActiveTimerDestructor, base::Unretained(this),
-        tether_network_guid_for_next_timer_));
-    tether_network_guid_to_timer_map_[tether_network_guid_for_next_timer_] =
-        mock_timer;
-    return base::WrapUnique(mock_timer);
-  }
-
- private:
-  void OnActiveTimerDestructor(const std::string& tether_network_guid) {
-    tether_network_guid_to_timer_map_.erase(
-        tether_network_guid_to_timer_map_.find(tether_network_guid));
-  }
-
-  std::string tether_network_guid_for_next_timer_;
-  std::unordered_map<std::string, ExtendedMockTimer*>
-      tether_network_guid_to_timer_map_;
-};
-
-}  // namespace
-
-// TODO(khorimoto): The test uses a FakeHostScanCache to keep an in-memory
-// cache of expected values. This has the potential to be confusing, since this
-// is the test for HostScanCache. Clean this up to avoid using FakeHostScanCache
-// if possible.
-class HostScanCacheTest : public NetworkStateTest {
- protected:
-  HostScanCacheTest() {}
-
-  void SetUp() override {
-    DBusThreadManager::Initialize();
-    NetworkStateTest::SetUp();
-    network_state_handler()->SetTetherTechnologyState(
-        NetworkStateHandler::TECHNOLOGY_ENABLED);
-
-    test_timer_factory_ = new TestTimerFactory();
-    fake_active_host_ = base::MakeUnique<FakeActiveHost>();
-    mock_tether_host_response_recorder_ =
-        base::MakeUnique<NiceMock<MockTetherHostResponseRecorder>>();
-    device_id_tether_network_guid_map_ =
-        base::MakeUnique<DeviceIdTetherNetworkGuidMap>();
-
-    ON_CALL(*mock_tether_host_response_recorder_,
-            GetPreviouslyConnectedHostIds())
-        .WillByDefault(
-            Invoke(this, &HostScanCacheTest::GetPreviouslyConnectedHostIds));
-
-    host_scan_cache_ = base::MakeUnique<HostScanCache>(
-        network_state_handler(), fake_active_host_.get(),
-        mock_tether_host_response_recorder_.get(),
-        device_id_tether_network_guid_map_.get());
-    host_scan_cache_->SetTimerFactoryForTest(
-        base::WrapUnique(test_timer_factory_));
-
-    // To track what is expected to be contained in the cache, maintain a
-    // FakeHostScanCache in memory and update it alongside |host_scan_cache_|.
-    // Use a std::vector to track which device IDs correspond to devices whose
-    // Tether networks' HasConnectedToHost fields are expected to be set.
-    expected_cache_ = base::MakeUnique<FakeHostScanCache>();
-    has_connected_to_host_device_ids_.clear();
-  }
-
-  void TearDown() override {
-    ShutdownNetworkState();
-    NetworkStateTest::TearDown();
-    DBusThreadManager::Shutdown();
-  }
-
-  void FireTimer(const std::string& tether_network_guid) {
-    ExtendedMockTimer* timer =
-        test_timer_factory_
-            ->tether_network_guid_to_timer_map()[tether_network_guid];
-    ASSERT_TRUE(timer);
-    timer->Fire();
-
-    // If the device whose correlated timer has fired is not the active host, it
-    // is expected to be removed from the cache.
-    EXPECT_EQ(fake_active_host_->GetTetherNetworkGuid(),
-              expected_cache_->active_host_tether_network_guid());
-    if (fake_active_host_->GetTetherNetworkGuid() != tether_network_guid) {
-      expected_cache_->RemoveHostScanResult(tether_network_guid);
-    }
-  }
-
-  std::vector<std::string> GetPreviouslyConnectedHostIds() const {
-    return has_connected_to_host_device_ids_;
-  }
-
-  void SetActiveHost(const std::string& tether_network_guid) {
-    fake_active_host_->SetActiveHostConnected(
-        device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid(
-            tether_network_guid),
-        tether_network_guid, "wifiNetworkGuid");
-    expected_cache_->set_active_host_tether_network_guid(tether_network_guid);
-  }
-
-  void SetHasConnectedToHost(const std::string& tether_network_guid) {
-    has_connected_to_host_device_ids_.push_back(
-        device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid(
-            tether_network_guid));
-    mock_tether_host_response_recorder_
-        ->NotifyObserversPreviouslyConnectedHostIdsChanged();
-  }
-
-  // Sets host scan results in the cache for the device at index |index|. Index
-  // can be from 0 to 3 and corresponds to the index of the constants declared
-  // at the top of this test file.
-  void SetCacheScanResultForDeviceIndex(int32_t index) {
-    // There are 4 sets of test constants.
-    ASSERT_TRUE(index >= 0 && index <= 3);
-
-    std::string tether_network_guid;
-    std::string device_name;
-    std::string carrier;
-    int battery_percentage;
-    int signal_strength;
-    bool setup_required;
-
-    switch (index) {
-      case 0:
-        tether_network_guid = kTetherGuid0;
-        device_name = kTetherDeviceName0;
-        carrier = kTetherCarrier0;
-        battery_percentage = kTetherBatteryPercentage0;
-        signal_strength = kTetherSignalStrength0;
-        setup_required = kTetherSetupRequired0;
-        break;
-      case 1:
-        tether_network_guid = kTetherGuid1;
-        device_name = kTetherDeviceName1;
-        carrier = kTetherCarrier1;
-        battery_percentage = kTetherBatteryPercentage1;
-        signal_strength = kTetherSignalStrength1;
-        setup_required = kTetherSetupRequired1;
-        break;
-      case 2:
-        tether_network_guid = kTetherGuid2;
-        device_name = kTetherDeviceName2;
-        carrier = kTetherCarrier2;
-        battery_percentage = kTetherBatteryPercentage2;
-        signal_strength = kTetherSignalStrength2;
-        setup_required = kTetherSetupRequired2;
-        break;
-      case 3:
-        tether_network_guid = kTetherGuid3;
-        device_name = kTetherDeviceName3;
-        carrier = kTetherCarrier3;
-        battery_percentage = kTetherBatteryPercentage3;
-        signal_strength = kTetherSignalStrength3;
-        setup_required = kTetherSetupRequired3;
-        break;
-      default:
-        NOTREACHED();
-        // Set values for |battery_percentage|, |signal_strength| and
-        // |setup_required| here to prevent a compiler warning which says that
-        // they may be unset at this point.
-        battery_percentage = 0;
-        signal_strength = 0;
-        setup_required = false;
-        break;
-    }
-
-    SetHostScanResult(tether_network_guid, device_name, carrier,
-                      battery_percentage, signal_strength, setup_required);
-  }
-
-  void SetHostScanResult(const std::string& tether_network_guid,
-                         const std::string& device_name,
-                         const std::string& carrier,
-                         int battery_percentage,
-                         int signal_strength,
-                         bool setup_required) {
-    test_timer_factory_->set_tether_network_guid_for_next_timer(
-        tether_network_guid);
-    host_scan_cache_->SetHostScanResult(tether_network_guid, device_name,
-                                        carrier, battery_percentage,
-                                        signal_strength, setup_required);
-    expected_cache_->SetHostScanResult(tether_network_guid, device_name,
-                                       carrier, battery_percentage,
-                                       signal_strength, setup_required);
-  }
-
-  void RemoveHostScanResult(const std::string& tether_network_guid) {
-    host_scan_cache_->RemoveHostScanResult(tether_network_guid);
-    expected_cache_->RemoveHostScanResult(tether_network_guid);
-  }
-
-  void ClearCacheExceptForActiveHost() {
-    host_scan_cache_->ClearCacheExceptForActiveHost();
-    expected_cache_->ClearCacheExceptForActiveHost();
-  }
-
-  bool HasConnectedToHost(const std::string& tether_network_guid) {
-    auto it =
-        std::find(has_connected_to_host_device_ids_.begin(),
-                  has_connected_to_host_device_ids_.end(), tether_network_guid);
-    return it != has_connected_to_host_device_ids_.end();
-  }
-
-  // Verifies that the information present in |expected_cache_| and
-  // |has_connected_to_host_device_ids_| mirrors what |host_scan_cache_| has set
-  // in NetworkStateHandler.
-  void VerifyCacheMatchesNetworkStack() {
-    for (auto& it : expected_cache_->cache()) {
-      const std::string tether_network_guid = it.first;
-      const FakeHostScanCache::CacheEntry cache_entry = it.second;
-
-      // Ensure that each entry in |expected_cache_| matches the
-      // corresponding entry in NetworkStateHandler.
-      const NetworkState* tether_network_state =
-          network_state_handler()->GetNetworkStateFromGuid(tether_network_guid);
-      ASSERT_TRUE(tether_network_state);
-      EXPECT_EQ(cache_entry.device_name, tether_network_state->name());
-      EXPECT_EQ(cache_entry.carrier, tether_network_state->carrier());
-      EXPECT_EQ(cache_entry.battery_percentage,
-                tether_network_state->battery_percentage());
-      EXPECT_EQ(cache_entry.signal_strength,
-                tether_network_state->signal_strength());
-      EXPECT_EQ(cache_entry.setup_required,
-                host_scan_cache_->DoesHostRequireSetup(tether_network_guid));
-      EXPECT_EQ(HasConnectedToHost(tether_network_guid),
-                tether_network_state->tether_has_connected_to_host());
-
-      // Ensure that each entry has an actively-running Timer.
-      auto timer_map_it =
-          test_timer_factory_->tether_network_guid_to_timer_map().begin();
-      EXPECT_NE(timer_map_it,
-                test_timer_factory_->tether_network_guid_to_timer_map().end());
-      EXPECT_TRUE(timer_map_it->second->IsRunning());
-    }
-  }
-
-  const base::test::ScopedTaskEnvironment scoped_task_environment_;
-
-  TestTimerFactory* test_timer_factory_;
-  std::unique_ptr<FakeActiveHost> fake_active_host_;
-  std::unique_ptr<NiceMock<MockTetherHostResponseRecorder>>
-      mock_tether_host_response_recorder_;
-  // TODO(hansberry): Use a fake for this when a real mapping scheme is created.
-  std::unique_ptr<DeviceIdTetherNetworkGuidMap>
-      device_id_tether_network_guid_map_;
-
-  std::vector<std::string> has_connected_to_host_device_ids_;
-  std::unique_ptr<FakeHostScanCache> expected_cache_;
-
-  std::unique_ptr<HostScanCache> host_scan_cache_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(HostScanCacheTest);
-};
-
-TEST_F(HostScanCacheTest, TestSetScanResultsAndLetThemExpire) {
-  SetCacheScanResultForDeviceIndex(0);
-  EXPECT_EQ(1u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  SetCacheScanResultForDeviceIndex(1);
-  EXPECT_EQ(2u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  SetCacheScanResultForDeviceIndex(2);
-  EXPECT_EQ(3u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  SetCacheScanResultForDeviceIndex(3);
-  EXPECT_EQ(4u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  FireTimer(kTetherGuid0);
-  EXPECT_EQ(3u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  FireTimer(kTetherGuid1);
-  EXPECT_EQ(2u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  FireTimer(kTetherGuid2);
-  EXPECT_EQ(1u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  FireTimer(kTetherGuid3);
-  EXPECT_TRUE(expected_cache_->empty());
-  VerifyCacheMatchesNetworkStack();
-}
-
-TEST_F(HostScanCacheTest, TestSetScanResultThenUpdateAndRemove) {
-  SetCacheScanResultForDeviceIndex(0);
-  EXPECT_EQ(1u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  // Change the fields for tether network with GUID |kTetherGuid0| to the
-  // fields corresponding to |kTetherGuid1|.
-  SetHostScanResult(kTetherGuid0, kTetherDeviceName0, kTetherCarrier1,
-                    kTetherBatteryPercentage1, kTetherSignalStrength1,
-                    kTetherSetupRequired1);
-  EXPECT_EQ(1u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  // Now, remove that result.
-  RemoveHostScanResult(kTetherGuid0);
-  EXPECT_TRUE(expected_cache_->empty());
-  VerifyCacheMatchesNetworkStack();
-}
-
-TEST_F(HostScanCacheTest, TestSetScanResult_SetActiveHost_ThenClear) {
-  SetCacheScanResultForDeviceIndex(0);
-  EXPECT_EQ(1u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  SetCacheScanResultForDeviceIndex(1);
-  EXPECT_EQ(2u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  SetCacheScanResultForDeviceIndex(2);
-  EXPECT_EQ(3u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  // Now, set the active host to be the device 0.
-  SetActiveHost(kTetherGuid0);
-
-  // Clear the cache except for the active host.
-  ClearCacheExceptForActiveHost();
-  EXPECT_EQ(1u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  // Attempt to remove the active host. This operation should fail since
-  // removing the active host from the cache is not allowed.
-  RemoveHostScanResult(kTetherGuid0);
-  EXPECT_EQ(1u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  // Fire the timer for the active host. Likewise, this should not result in the
-  // cache entry being removed.
-  FireTimer(kTetherGuid0);
-  EXPECT_EQ(1u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  // Now, unset the active host.
-  SetActiveHost("");
-
-  // Removing the device should now succeed.
-  RemoveHostScanResult(kTetherGuid0);
-  EXPECT_TRUE(expected_cache_->empty());
-  VerifyCacheMatchesNetworkStack();
-}
-
-TEST_F(HostScanCacheTest, TestHasConnectedToHost) {
-  // Before the test starts, set device 0 as having already connected.
-  SetHasConnectedToHost(kTetherGuid0);
-
-  SetCacheScanResultForDeviceIndex(0);
-  EXPECT_EQ(1u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  SetCacheScanResultForDeviceIndex(1);
-  EXPECT_EQ(2u, expected_cache_->size());
-  VerifyCacheMatchesNetworkStack();
-
-  // Simulate a connection to device 1.
-  SetActiveHost(kTetherGuid1);
-  SetHasConnectedToHost(kTetherGuid1);
-  VerifyCacheMatchesNetworkStack();
-}
-
-}  // namespace tether
-
-}  // namespace chromeos
diff --git a/chromeos/components/tether/host_scanner.cc b/chromeos/components/tether/host_scanner.cc
index 7e34a820..13af4f28 100644
--- a/chromeos/components/tether/host_scanner.cc
+++ b/chromeos/components/tether/host_scanner.cc
@@ -11,6 +11,7 @@
 #include "chromeos/components/tether/device_id_tether_network_guid_map.h"
 #include "chromeos/components/tether/device_status_util.h"
 #include "chromeos/components/tether/host_scan_cache.h"
+#include "chromeos/components/tether/master_host_scan_cache.h"
 #include "chromeos/components/tether/tether_host_fetcher.h"
 #include "chromeos/network/network_state.h"
 #include "components/cryptauth/remote_device_loader.h"
@@ -49,9 +50,10 @@
   if (previous_scan_time_.is_null())
     return false;
 
+  // TODO(khorimoto): Don't depend on MasterHostScanCache here.
   base::TimeDelta difference = clock_->Now() - previous_scan_time_;
   return difference.InMinutes() <
-         HostScanCache::kNumMinutesBeforeCacheEntryExpires;
+         MasterHostScanCache::kNumMinutesBeforeCacheEntryExpires;
 }
 
 void HostScanner::StartScan() {
@@ -145,10 +147,16 @@
                         &signal_strength);
 
   host_scan_cache_->SetHostScanResult(
-      device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId(
-          remote_device.GetDeviceId()),
-      remote_device.name, carrier, battery_percentage, signal_strength,
-      scanned_device_info.setup_required);
+      *HostScanCacheEntry::Builder()
+           .SetTetherNetworkGuid(device_id_tether_network_guid_map_
+                                     ->GetTetherNetworkGuidForDeviceId(
+                                         remote_device.GetDeviceId()))
+           .SetDeviceName(remote_device.name)
+           .SetCarrier(carrier)
+           .SetBatteryPercentage(battery_percentage)
+           .SetSignalStrength(signal_strength)
+           .SetSetupRequired(scanned_device_info.setup_required)
+           .Build());
 }
 
 void HostScanner::RecordHostScanResult(HostScanResultEventType event_type) {
diff --git a/chromeos/components/tether/host_scanner_unittest.cc b/chromeos/components/tether/host_scanner_unittest.cc
index d9bbc60..8faa7a083 100644
--- a/chromeos/components/tether/host_scanner_unittest.cc
+++ b/chromeos/components/tether/host_scanner_unittest.cc
@@ -20,6 +20,7 @@
 #include "chromeos/components/tether/fake_tether_host_fetcher.h"
 #include "chromeos/components/tether/host_scan_device_prioritizer.h"
 #include "chromeos/components/tether/host_scanner.h"
+#include "chromeos/components/tether/master_host_scan_cache.h"
 #include "chromeos/components/tether/mock_tether_host_response_recorder.h"
 #include "chromeos/components/tether/proto_test_util.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
@@ -283,40 +284,40 @@
       std::string tether_network_guid =
           device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId(
               scanned_device_info.remote_device.GetDeviceId());
-      const FakeHostScanCache::CacheEntry* cache_item =
+      const HostScanCacheEntry* entry =
           fake_host_scan_cache_->GetCacheEntry(tether_network_guid);
-      ASSERT_TRUE(cache_item);
+      ASSERT_TRUE(entry);
       VerifyScannedDeviceInfoAndCacheEntryAreEquivalent(scanned_device_info,
-                                                        *cache_item);
+                                                        *entry);
     }
   }
 
   void VerifyScannedDeviceInfoAndCacheEntryAreEquivalent(
       const HostScannerOperation::ScannedDeviceInfo& scanned_device_info,
-      const FakeHostScanCache::CacheEntry& cache_item) {
-    EXPECT_EQ(scanned_device_info.remote_device.name, cache_item.device_name);
+      const HostScanCacheEntry& entry) {
+    EXPECT_EQ(scanned_device_info.remote_device.name, entry.device_name);
 
     const DeviceStatus& status = scanned_device_info.device_status;
     if (!status.has_cell_provider() || status.cell_provider().empty())
-      EXPECT_EQ("unknown-carrier", cache_item.carrier);
+      EXPECT_EQ("unknown-carrier", entry.carrier);
     else
-      EXPECT_EQ(status.cell_provider(), cache_item.carrier);
+      EXPECT_EQ(status.cell_provider(), entry.carrier);
 
     if (!status.has_battery_percentage() || status.battery_percentage() > 100)
-      EXPECT_EQ(100, cache_item.battery_percentage);
+      EXPECT_EQ(100, entry.battery_percentage);
     else if (status.battery_percentage() < 0)
-      EXPECT_EQ(0, cache_item.battery_percentage);
+      EXPECT_EQ(0, entry.battery_percentage);
     else
-      EXPECT_EQ(status.battery_percentage(), cache_item.battery_percentage);
+      EXPECT_EQ(status.battery_percentage(), entry.battery_percentage);
 
     if (!status.has_connection_strength() || status.connection_strength() > 4)
-      EXPECT_EQ(100, cache_item.signal_strength);
+      EXPECT_EQ(100, entry.signal_strength);
     else if (status.connection_strength() < 0)
-      EXPECT_EQ(0, cache_item.signal_strength);
+      EXPECT_EQ(0, entry.signal_strength);
     else
-      EXPECT_EQ(status.connection_strength() * 25, cache_item.signal_strength);
+      EXPECT_EQ(status.connection_strength() * 25, entry.signal_strength);
 
-    EXPECT_EQ(scanned_device_info.setup_required, cache_item.setup_required);
+    EXPECT_EQ(scanned_device_info.setup_required, entry.setup_required);
   }
 
   const std::vector<cryptauth::RemoteDevice> test_devices_;
@@ -570,7 +571,8 @@
   // We have just scanned.
   EXPECT_TRUE(host_scanner_->HasRecentlyScanned());
 
-  int time_limit_minutes = HostScanCache::kNumMinutesBeforeCacheEntryExpires;
+  int time_limit_minutes =
+      MasterHostScanCache::kNumMinutesBeforeCacheEntryExpires;
   int time_limit_seconds = time_limit_minutes * 60;
   int time_limit_half_seconds = time_limit_seconds / 2;
   int time_limit_threshold_seconds =
diff --git a/chromeos/components/tether/initializer.cc b/chromeos/components/tether/initializer.cc
index b6af3b5..2583604 100644
--- a/chromeos/components/tether/initializer.cc
+++ b/chromeos/components/tether/initializer.cc
@@ -9,16 +9,16 @@
 #include "chromeos/components/tether/active_host_network_state_updater.h"
 #include "chromeos/components/tether/ble_connection_manager.h"
 #include "chromeos/components/tether/device_id_tether_network_guid_map.h"
-#include "chromeos/components/tether/host_scan_cache.h"
 #include "chromeos/components/tether/host_scan_device_prioritizer_impl.h"
 #include "chromeos/components/tether/host_scan_scheduler.h"
 #include "chromeos/components/tether/host_scanner.h"
 #include "chromeos/components/tether/keep_alive_scheduler.h"
+#include "chromeos/components/tether/master_host_scan_cache.h"
 #include "chromeos/components/tether/network_configuration_remover.h"
 #include "chromeos/components/tether/network_connection_handler_tether_delegate.h"
 #include "chromeos/components/tether/notification_presenter.h"
 #include "chromeos/components/tether/tether_connector.h"
-#include "chromeos/components/tether/tether_disconnector.h"
+#include "chromeos/components/tether/tether_disconnector_impl.h"
 #include "chromeos/components/tether/tether_host_fetcher.h"
 #include "chromeos/components/tether/tether_host_response_recorder.h"
 #include "chromeos/components/tether/tether_network_disconnection_handler.h"
@@ -94,6 +94,7 @@
 void Initializer::RegisterProfilePrefs(PrefRegistrySimple* registry) {
   ActiveHost::RegisterPrefs(registry);
   TetherHostResponseRecorder::RegisterPrefs(registry);
+  TetherDisconnectorImpl::RegisterPrefs(registry);
 }
 
 Initializer::Initializer(
@@ -198,7 +199,7 @@
   active_host_network_state_updater_ =
       base::MakeUnique<ActiveHostNetworkStateUpdater>(active_host_.get(),
                                                       network_state_handler_);
-  host_scan_cache_ = base::MakeUnique<HostScanCache>(
+  host_scan_cache_ = base::MakeUnique<MasterHostScanCache>(
       network_state_handler_, active_host_.get(),
       tether_host_response_recorder_.get(),
       device_id_tether_network_guid_map_.get());
@@ -222,11 +223,11 @@
   network_configuration_remover_ =
       base::MakeUnique<NetworkConfigurationRemover>(
           network_state_handler_, managed_network_configuration_handler_);
-  tether_disconnector_ = base::MakeUnique<TetherDisconnector>(
+  tether_disconnector_ = base::MakeUnique<TetherDisconnectorImpl>(
       network_connection_handler_, network_state_handler_, active_host_.get(),
       ble_connection_manager_.get(), network_configuration_remover_.get(),
       tether_connector_.get(), device_id_tether_network_guid_map_.get(),
-      tether_host_fetcher_.get());
+      tether_host_fetcher_.get(), pref_service_);
   tether_network_disconnection_handler_ =
       base::MakeUnique<TetherNetworkDisconnectionHandler>(
           active_host_.get(), network_state_handler_,
diff --git a/chromeos/components/tether/keep_alive_scheduler.cc b/chromeos/components/tether/keep_alive_scheduler.cc
index 02a47e4..59dafba 100644
--- a/chromeos/components/tether/keep_alive_scheduler.cc
+++ b/chromeos/components/tether/keep_alive_scheduler.cc
@@ -89,14 +89,19 @@
   NormalizeDeviceStatus(*device_status, &carrier, &battery_percentage,
                         &signal_strength);
 
-  // Update the cache. Note that "false" is passed for the |setup_required|
-  // parameter because it is assumed that setup is no longer required for an
-  // active connection attempt.
+  // Update the cache. Note that SetSetupRequired(false) is called because it is
+  // assumed that setup is no longer required for an active connection attempt.
   host_scan_cache_->SetHostScanResult(
-      device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId(
-          device_copy.GetDeviceId()),
-      device_copy.name, carrier, battery_percentage, signal_strength,
-      false /* setup_required */);
+      *HostScanCacheEntry::Builder()
+           .SetTetherNetworkGuid(device_id_tether_network_guid_map_
+                                     ->GetTetherNetworkGuidForDeviceId(
+                                         remote_device.GetDeviceId()))
+           .SetDeviceName(device_copy.name)
+           .SetCarrier(carrier)
+           .SetBatteryPercentage(battery_percentage)
+           .SetSignalStrength(signal_strength)
+           .SetSetupRequired(false)
+           .Build());
 }
 
 void KeepAliveScheduler::SendKeepAliveTickle() {
diff --git a/chromeos/components/tether/keep_alive_scheduler_unittest.cc b/chromeos/components/tether/keep_alive_scheduler_unittest.cc
index 90ed222..ef61088 100644
--- a/chromeos/components/tether/keep_alive_scheduler_unittest.cc
+++ b/chromeos/components/tether/keep_alive_scheduler_unittest.cc
@@ -134,10 +134,9 @@
                           const std::string& carrier,
                           int battery_percentage,
                           int signal_strength) {
-    const FakeHostScanCache::CacheEntry* entry =
-        fake_host_scan_cache_->GetCacheEntry(
-            device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId(
-                remote_device.GetDeviceId()));
+    const HostScanCacheEntry* entry = fake_host_scan_cache_->GetCacheEntry(
+        device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId(
+            remote_device.GetDeviceId()));
     ASSERT_TRUE(entry);
     EXPECT_EQ(carrier, entry->carrier);
     EXPECT_EQ(battery_percentage, entry->battery_percentage);
diff --git a/chromeos/components/tether/master_host_scan_cache.cc b/chromeos/components/tether/master_host_scan_cache.cc
new file mode 100644
index 0000000..dce65d8
--- /dev/null
+++ b/chromeos/components/tether/master_host_scan_cache.cc
@@ -0,0 +1,224 @@
+// 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 "chromeos/components/tether/master_host_scan_cache.h"
+
+#include <algorithm>
+
+#include "base/bind.h"
+#include "base/memory/ptr_util.h"
+#include "chromeos/components/tether/active_host.h"
+#include "chromeos/components/tether/device_id_tether_network_guid_map.h"
+#include "chromeos/components/tether/tether_host_response_recorder.h"
+#include "chromeos/components/tether/timer_factory.h"
+#include "chromeos/network/network_state_handler.h"
+#include "components/proximity_auth/logging/logging.h"
+
+namespace chromeos {
+
+namespace tether {
+
+MasterHostScanCache::MasterHostScanCache(
+    NetworkStateHandler* network_state_handler,
+    ActiveHost* active_host,
+    TetherHostResponseRecorder* tether_host_response_recorder,
+    DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map)
+    : timer_factory_(base::MakeUnique<TimerFactory>()),
+      network_state_handler_(network_state_handler),
+      active_host_(active_host),
+      tether_host_response_recorder_(tether_host_response_recorder),
+      device_id_tether_network_guid_map_(device_id_tether_network_guid_map),
+      weak_ptr_factory_(this) {
+  tether_host_response_recorder_->AddObserver(this);
+}
+
+MasterHostScanCache::~MasterHostScanCache() {
+  tether_host_response_recorder_->RemoveObserver(this);
+}
+
+void MasterHostScanCache::SetHostScanResult(const HostScanCacheEntry& entry) {
+  auto found_iter = tether_guid_to_timer_map_.find(entry.tether_network_guid);
+
+  if (found_iter == tether_guid_to_timer_map_.end()) {
+    // Add the Tether network to NetworkStateHandler and create an associated
+    // Timer.
+    network_state_handler_->AddTetherNetworkState(
+        entry.tether_network_guid, entry.device_name, entry.carrier,
+        entry.battery_percentage, entry.signal_strength,
+        HasConnectedToHost(entry.tether_network_guid));
+    tether_guid_to_timer_map_.emplace(entry.tether_network_guid,
+                                      timer_factory_->CreateOneShotTimer());
+
+    PA_LOG(INFO) << "Added scan result for Tether network with GUID "
+                 << entry.tether_network_guid << ". "
+                 << "Device name: " << entry.device_name << ", "
+                 << "carrier: " << entry.carrier << ", "
+                 << "battery percentage: " << entry.battery_percentage << ", "
+                 << "signal strength: " << entry.signal_strength;
+  } else {
+    // Update the existing network and stop the associated Timer.
+    network_state_handler_->UpdateTetherNetworkProperties(
+        entry.tether_network_guid, entry.carrier, entry.battery_percentage,
+        entry.signal_strength);
+    found_iter->second->Stop();
+
+    PA_LOG(INFO) << "Updated scan result for Tether network with GUID "
+                 << entry.tether_network_guid << ". "
+                 << "New carrier: " << entry.carrier << ", "
+                 << "new battery percentage: " << entry.battery_percentage
+                 << ", new signal strength: " << entry.signal_strength;
+  }
+
+  if (entry.setup_required)
+    setup_required_tether_guids_.insert(entry.tether_network_guid);
+  else
+    setup_required_tether_guids_.erase(entry.tether_network_guid);
+
+  StartTimer(entry.tether_network_guid);
+}
+
+bool MasterHostScanCache::RemoveHostScanResult(
+    const std::string& tether_network_guid) {
+  DCHECK(!tether_network_guid.empty());
+
+  auto it = tether_guid_to_timer_map_.find(tether_network_guid);
+  if (it == tether_guid_to_timer_map_.end()) {
+    PA_LOG(ERROR) << "Attempted to remove a host scan result which does not "
+                  << "exist in the cache. GUID: " << tether_network_guid;
+    return false;
+  }
+
+  if (active_host_->GetTetherNetworkGuid() == tether_network_guid) {
+    PA_LOG(ERROR) << "RemoveHostScanResult() called for Tether network with "
+                  << "GUID " << tether_network_guid << ", but the "
+                  << "corresponding device is the active host. Not removing "
+                  << "this scan result from the cache.";
+    return false;
+  }
+
+  tether_guid_to_timer_map_.erase(it);
+  setup_required_tether_guids_.erase(tether_network_guid);
+  return network_state_handler_->RemoveTetherNetworkState(tether_network_guid);
+}
+
+void MasterHostScanCache::ClearCacheExceptForActiveHost() {
+  // Create a list of all Tether network GUIDs serving as keys to
+  // |tether_guid_to_timer_map_|.
+  std::vector<std::string> tether_network_guids;
+  tether_network_guids.reserve(tether_guid_to_timer_map_.size());
+  for (auto& it : tether_guid_to_timer_map_)
+    tether_network_guids.push_back(it.first);
+
+  std::string active_host_tether_guid = active_host_->GetTetherNetworkGuid();
+  if (active_host_tether_guid.empty()) {
+    PA_LOG(INFO) << "Clearing all " << tether_guid_to_timer_map_.size() << " "
+                 << "entries from the cache.";
+  } else {
+    PA_LOG(INFO) << "Clearing " << (tether_guid_to_timer_map_.size() - 1) << " "
+                 << "of the " << tether_guid_to_timer_map_.size() << " "
+                 << "entries from the cache. Not removing the entry "
+                 << "corresponding to the Tether network with GUID "
+                 << active_host_tether_guid << " because it represents the "
+                 << "active host.";
+  }
+
+  // Iterate through the keys, removing all scan results not corresponding to
+  // the active host. Iteration is done via a list of pre-computed keys instead
+  // if iterating through the map because RemoteHostScanResult() will remove
+  // key/value pairs from the map, which would invalidate the map iterator.
+  for (auto& tether_network_guid : tether_network_guids) {
+    if (active_host_->GetTetherNetworkGuid() == tether_network_guid) {
+      // Do not remove the active host from the cache.
+      continue;
+    }
+
+    RemoveHostScanResult(tether_network_guid);
+  }
+}
+
+bool MasterHostScanCache::DoesHostRequireSetup(
+    const std::string& tether_network_guid) {
+  return setup_required_tether_guids_.find(tether_network_guid) !=
+         setup_required_tether_guids_.end();
+}
+
+void MasterHostScanCache::OnPreviouslyConnectedHostIdsChanged() {
+  for (auto& map_entry : tether_guid_to_timer_map_) {
+    const std::string& tether_network_guid = map_entry.first;
+    if (!HasConnectedToHost(tether_network_guid))
+      continue;
+
+    // If a the current device has connected to the Tether network with GUID
+    // |tether_network_guid|, alert |network_state_handler_|. Note that this
+    // function is a no-op if it is called on a network which already has its
+    // HasConnectedToHost property set to true.
+    bool update_successful =
+        network_state_handler_->SetTetherNetworkHasConnectedToHost(
+            tether_network_guid);
+
+    if (update_successful) {
+      PA_LOG(INFO) << "Successfully set the HasConnectedToHost property of "
+                   << "the Tether network with GUID " << tether_network_guid
+                   << " to true.";
+    }
+  }
+}
+
+void MasterHostScanCache::SetTimerFactoryForTest(
+    std::unique_ptr<TimerFactory> timer_factory_for_test) {
+  timer_factory_ = std::move(timer_factory_for_test);
+}
+
+bool MasterHostScanCache::HasConnectedToHost(
+    const std::string& tether_network_guid) {
+  std::string device_id =
+      device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid(
+          tether_network_guid);
+  std::vector<std::string> connected_device_ids =
+      tether_host_response_recorder_->GetPreviouslyConnectedHostIds();
+  return std::find(connected_device_ids.begin(), connected_device_ids.end(),
+                   device_id) != connected_device_ids.end();
+}
+
+void MasterHostScanCache::StartTimer(const std::string& tether_network_guid) {
+  auto found_iter = tether_guid_to_timer_map_.find(tether_network_guid);
+  DCHECK(found_iter != tether_guid_to_timer_map_.end());
+  DCHECK(!found_iter->second->IsRunning());
+
+  PA_LOG(INFO) << "Starting host scan cache timer for Tether network with GUID "
+               << tether_network_guid << ". Will fire in "
+               << kNumMinutesBeforeCacheEntryExpires << " minutes.";
+
+  found_iter->second->Start(
+      FROM_HERE,
+      base::TimeDelta::FromMinutes(kNumMinutesBeforeCacheEntryExpires),
+      base::Bind(&MasterHostScanCache::OnTimerFired,
+                 weak_ptr_factory_.GetWeakPtr(), tether_network_guid));
+}
+
+void MasterHostScanCache::OnTimerFired(const std::string& tether_network_guid) {
+  if (active_host_->GetTetherNetworkGuid() == tether_network_guid) {
+    // Log as a warning. This situation should be uncommon in practice since
+    // KeepAliveScheduler should schedule a new keep-alive status update every
+    // 4 minutes.
+    PA_LOG(WARNING) << "Timer fired for Tether network GUID "
+                    << tether_network_guid << ", but the corresponding device "
+                    << "is the active host. Restarting timer.";
+
+    // If the Timer which fired corresponds to the active host, do not remove
+    // the cache entry. The active host must always remain in the cache so that
+    // the UI can reflect that it is the connecting/connected network. In this
+    // case, just restart the timer.
+    StartTimer(tether_network_guid);
+    return;
+  }
+
+  PA_LOG(INFO) << "Timer fired for Tether network GUID " << tether_network_guid
+               << ". Removing stale scan result.";
+  RemoveHostScanResult(tether_network_guid);
+}
+
+}  // namespace tether
+
+}  // namespace chromeos
diff --git a/chromeos/components/tether/master_host_scan_cache.h b/chromeos/components/tether/master_host_scan_cache.h
new file mode 100644
index 0000000..06018a27
--- /dev/null
+++ b/chromeos/components/tether/master_host_scan_cache.h
@@ -0,0 +1,96 @@
+// 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 CHROMEOS_COMPONENTS_TETHER_MASTER_HOST_SCAN_CACHE_H_
+#define CHROMEOS_COMPONENTS_TETHER_MASTER_HOST_SCAN_CACHE_H_
+
+#include <memory>
+#include <unordered_map>
+
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "base/timer/timer.h"
+#include "chromeos/components/tether/host_scan_cache.h"
+#include "chromeos/components/tether/tether_host_response_recorder.h"
+
+namespace chromeos {
+
+class NetworkStateHandler;
+
+namespace tether {
+
+class ActiveHost;
+class DeviceIdTetherNetworkGuidMap;
+class TetherHostResponseRecorder;
+class TimerFactory;
+
+// Master host scan cache, which stores host scan results in the network stack.
+// TODO(khorimoto): Add the ability to store tether host scan results
+// persistently so that they can be recovered after a browser crash.
+class MasterHostScanCache : public HostScanCache,
+                            public TetherHostResponseRecorder::Observer {
+ public:
+  // The number of minutes that a cache entry is considered to be valid before
+  // it becomes stale. Once a cache entry is inserted, it will be automatically
+  // removed after this amount of time passes unless it corresponds to the
+  // active host. This value was chosen for two reasons:
+  //     (1) Tether properties such as battery percentage and signal strength
+  //         are ephemeral in nature, so keeping these values cached for more
+  //         than a short period makes it likely that the values will be wrong.
+  //     (2) Tether networks rely on proximity to a tether host device, so it is
+  //         possible that host devices have physically moved away from each
+  //         other. We assume that the devices do not stay in proximity to one
+  //         another until a new scan result is received which proves that they
+  //         are still within the distance needed to communicate.
+  static constexpr int kNumMinutesBeforeCacheEntryExpires = 5;
+
+  MasterHostScanCache(
+      NetworkStateHandler* network_state_handler,
+      ActiveHost* active_host,
+      TetherHostResponseRecorder* tether_host_response_recorder,
+      DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map);
+  ~MasterHostScanCache() override;
+
+  // HostScanCache:
+  void SetHostScanResult(const HostScanCacheEntry& entry) override;
+  bool RemoveHostScanResult(const std::string& tether_network_guid) override;
+  void ClearCacheExceptForActiveHost() override;
+  bool DoesHostRequireSetup(const std::string& tether_network_guid) override;
+
+  // TetherHostResponseRecorder::Observer:
+  void OnPreviouslyConnectedHostIdsChanged() override;
+
+ private:
+  friend class MasterHostScanCacheTest;
+
+  void SetTimerFactoryForTest(
+      std::unique_ptr<TimerFactory> timer_factory_for_test);
+
+  bool HasConnectedToHost(const std::string& tether_network_guid);
+  void StartTimer(const std::string& tether_network_guid);
+  void OnTimerFired(const std::string& tether_network_guid);
+
+  std::unique_ptr<TimerFactory> timer_factory_;
+  NetworkStateHandler* network_state_handler_;
+  ActiveHost* active_host_;
+  TetherHostResponseRecorder* tether_host_response_recorder_;
+  DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map_;
+
+  // Maps from the Tether network GUID to a Timer object. While a scan result is
+  // active in the cache, the corresponding Timer object starts running; if the
+  // timer fires, the result is removed (unless it corresponds to the active
+  // host).
+  std::unordered_map<std::string, std::unique_ptr<base::Timer>>
+      tether_guid_to_timer_map_;
+  std::unordered_set<std::string> setup_required_tether_guids_;
+  base::WeakPtrFactory<MasterHostScanCache> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(MasterHostScanCache);
+};
+
+}  // namespace tether
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_COMPONENTS_TETHER_MASTER_HOST_SCAN_CACHE_H_
diff --git a/chromeos/components/tether/master_host_scan_cache_unittest.cc b/chromeos/components/tether/master_host_scan_cache_unittest.cc
new file mode 100644
index 0000000..9632631
--- /dev/null
+++ b/chromeos/components/tether/master_host_scan_cache_unittest.cc
@@ -0,0 +1,446 @@
+// 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 "chromeos/components/tether/master_host_scan_cache.h"
+
+#include <memory>
+#include <unordered_map>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/memory/ptr_util.h"
+#include "base/test/scoped_task_environment.h"
+#include "base/timer/mock_timer.h"
+#include "chromeos/components/tether/device_id_tether_network_guid_map.h"
+#include "chromeos/components/tether/fake_active_host.h"
+#include "chromeos/components/tether/fake_host_scan_cache.h"
+#include "chromeos/components/tether/mock_tether_host_response_recorder.h"
+#include "chromeos/components/tether/timer_factory.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/network/network_state.h"
+#include "chromeos/network/network_state_handler.h"
+#include "chromeos/network/network_state_test.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::NiceMock;
+using testing::Invoke;
+
+namespace chromeos {
+
+namespace tether {
+
+namespace {
+
+const char kTetherGuid0[] = "kTetherGuid0";
+const char kTetherGuid1[] = "kTetherGuid1";
+const char kTetherGuid2[] = "kTetherGuid2";
+const char kTetherGuid3[] = "kTetherGuid3";
+
+const char kTetherDeviceName0[] = "kDeviceName0";
+const char kTetherDeviceName1[] = "kDeviceName1";
+const char kTetherDeviceName2[] = "kDeviceName2";
+const char kTetherDeviceName3[] = "kDeviceName3";
+
+const char kTetherCarrier0[] = "kTetherCarrier0";
+const char kTetherCarrier1[] = "kTetherCarrier1";
+const char kTetherCarrier2[] = "kTetherCarrier2";
+const char kTetherCarrier3[] = "kTetherCarrier3";
+
+const int kTetherBatteryPercentage0 = 20;
+const int kTetherBatteryPercentage1 = 40;
+const int kTetherBatteryPercentage2 = 60;
+const int kTetherBatteryPercentage3 = 80;
+
+const int kTetherSignalStrength0 = 25;
+const int kTetherSignalStrength1 = 50;
+const int kTetherSignalStrength2 = 75;
+const int kTetherSignalStrength3 = 100;
+
+const bool kTetherSetupRequired0 = true;
+const bool kTetherSetupRequired1 = false;
+const bool kTetherSetupRequired2 = true;
+const bool kTetherSetupRequired3 = false;
+
+// MockTimer which invokes a callback in its destructor.
+class ExtendedMockTimer : public base::MockTimer {
+ public:
+  explicit ExtendedMockTimer(const base::Closure& destructor_callback)
+      : base::MockTimer(true /* retain_user_task */, false /* is_repeating */),
+        destructor_callback_(destructor_callback) {}
+
+  ~ExtendedMockTimer() override { destructor_callback_.Run(); }
+
+ private:
+  base::Closure destructor_callback_;
+};
+
+class TestTimerFactory : public TimerFactory {
+ public:
+  TestTimerFactory() {}
+  ~TestTimerFactory() override {}
+
+  std::unordered_map<std::string, ExtendedMockTimer*>&
+  tether_network_guid_to_timer_map() {
+    return tether_network_guid_to_timer_map_;
+  }
+
+  void set_tether_network_guid_for_next_timer(
+      const std::string& tether_network_guid_for_next_timer) {
+    tether_network_guid_for_next_timer_ = tether_network_guid_for_next_timer;
+  }
+
+  // TimerFactory:
+  std::unique_ptr<base::Timer> CreateOneShotTimer() override {
+    EXPECT_FALSE(tether_network_guid_for_next_timer_.empty());
+    ExtendedMockTimer* mock_timer = new ExtendedMockTimer(base::Bind(
+        &TestTimerFactory::OnActiveTimerDestructor, base::Unretained(this),
+        tether_network_guid_for_next_timer_));
+    tether_network_guid_to_timer_map_[tether_network_guid_for_next_timer_] =
+        mock_timer;
+    return base::WrapUnique(mock_timer);
+  }
+
+ private:
+  void OnActiveTimerDestructor(const std::string& tether_network_guid) {
+    tether_network_guid_to_timer_map_.erase(
+        tether_network_guid_to_timer_map_.find(tether_network_guid));
+  }
+
+  std::string tether_network_guid_for_next_timer_;
+  std::unordered_map<std::string, ExtendedMockTimer*>
+      tether_network_guid_to_timer_map_;
+};
+
+}  // namespace
+
+// TODO(khorimoto): The test uses a FakeHostScanCache to keep an in-memory
+// cache of expected values. This has the potential to be confusing, since this
+// is the test for MasterHostScanCache. Clean this up to avoid using
+// FakeHostScanCache if possible.
+class MasterHostScanCacheTest : public NetworkStateTest {
+ protected:
+  MasterHostScanCacheTest() {}
+
+  void SetUp() override {
+    DBusThreadManager::Initialize();
+    NetworkStateTest::SetUp();
+    network_state_handler()->SetTetherTechnologyState(
+        NetworkStateHandler::TECHNOLOGY_ENABLED);
+
+    test_timer_factory_ = new TestTimerFactory();
+    fake_active_host_ = base::MakeUnique<FakeActiveHost>();
+    mock_tether_host_response_recorder_ =
+        base::MakeUnique<NiceMock<MockTetherHostResponseRecorder>>();
+    device_id_tether_network_guid_map_ =
+        base::MakeUnique<DeviceIdTetherNetworkGuidMap>();
+
+    ON_CALL(*mock_tether_host_response_recorder_,
+            GetPreviouslyConnectedHostIds())
+        .WillByDefault(Invoke(
+            this, &MasterHostScanCacheTest::GetPreviouslyConnectedHostIds));
+
+    host_scan_cache_ = base::MakeUnique<MasterHostScanCache>(
+        network_state_handler(), fake_active_host_.get(),
+        mock_tether_host_response_recorder_.get(),
+        device_id_tether_network_guid_map_.get());
+    host_scan_cache_->SetTimerFactoryForTest(
+        base::WrapUnique(test_timer_factory_));
+
+    // To track what is expected to be contained in the cache, maintain a
+    // FakeHostScanCache in memory and update it alongside |host_scan_cache_|.
+    // Use a std::vector to track which device IDs correspond to devices whose
+    // Tether networks' HasConnectedToHost fields are expected to be set.
+    expected_cache_ = base::MakeUnique<FakeHostScanCache>();
+    has_connected_to_host_device_ids_.clear();
+  }
+
+  void TearDown() override {
+    ShutdownNetworkState();
+    NetworkStateTest::TearDown();
+    DBusThreadManager::Shutdown();
+  }
+
+  void FireTimer(const std::string& tether_network_guid) {
+    ExtendedMockTimer* timer =
+        test_timer_factory_
+            ->tether_network_guid_to_timer_map()[tether_network_guid];
+    ASSERT_TRUE(timer);
+    timer->Fire();
+
+    // If the device whose correlated timer has fired is not the active host, it
+    // is expected to be removed from the cache.
+    EXPECT_EQ(fake_active_host_->GetTetherNetworkGuid(),
+              expected_cache_->active_host_tether_network_guid());
+    if (fake_active_host_->GetTetherNetworkGuid() != tether_network_guid) {
+      expected_cache_->RemoveHostScanResult(tether_network_guid);
+    }
+  }
+
+  std::vector<std::string> GetPreviouslyConnectedHostIds() const {
+    return has_connected_to_host_device_ids_;
+  }
+
+  void SetActiveHost(const std::string& tether_network_guid) {
+    fake_active_host_->SetActiveHostConnected(
+        device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid(
+            tether_network_guid),
+        tether_network_guid, "wifiNetworkGuid");
+    expected_cache_->set_active_host_tether_network_guid(tether_network_guid);
+  }
+
+  void SetHasConnectedToHost(const std::string& tether_network_guid) {
+    has_connected_to_host_device_ids_.push_back(
+        device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid(
+            tether_network_guid));
+    mock_tether_host_response_recorder_
+        ->NotifyObserversPreviouslyConnectedHostIdsChanged();
+  }
+
+  // Sets host scan results in the cache for the device at index |index|. Index
+  // can be from 0 to 3 and corresponds to the index of the constants declared
+  // at the top of this test file.
+  void SetCacheScanResultForDeviceIndex(int32_t index) {
+    // There are 4 sets of test constants.
+    ASSERT_TRUE(index >= 0 && index <= 3);
+
+    HostScanCacheEntry::Builder builder;
+
+    switch (index) {
+      case 0:
+        builder.SetTetherNetworkGuid(kTetherGuid0)
+            .SetDeviceName(kTetherDeviceName0)
+            .SetCarrier(kTetherCarrier0)
+            .SetBatteryPercentage(kTetherBatteryPercentage0)
+            .SetSignalStrength(kTetherSignalStrength0)
+            .SetSetupRequired(kTetherSetupRequired0);
+        break;
+      case 1:
+        builder.SetTetherNetworkGuid(kTetherGuid1)
+            .SetDeviceName(kTetherDeviceName1)
+            .SetCarrier(kTetherCarrier1)
+            .SetBatteryPercentage(kTetherBatteryPercentage1)
+            .SetSignalStrength(kTetherSignalStrength1)
+            .SetSetupRequired(kTetherSetupRequired1);
+        break;
+      case 2:
+        builder.SetTetherNetworkGuid(kTetherGuid2)
+            .SetDeviceName(kTetherDeviceName2)
+            .SetCarrier(kTetherCarrier2)
+            .SetBatteryPercentage(kTetherBatteryPercentage2)
+            .SetSignalStrength(kTetherSignalStrength2)
+            .SetSetupRequired(kTetherSetupRequired2);
+        break;
+      case 3:
+        builder.SetTetherNetworkGuid(kTetherGuid3)
+            .SetDeviceName(kTetherDeviceName3)
+            .SetCarrier(kTetherCarrier3)
+            .SetBatteryPercentage(kTetherBatteryPercentage3)
+            .SetSignalStrength(kTetherSignalStrength3)
+            .SetSetupRequired(kTetherSetupRequired3);
+        break;
+      default:
+        NOTREACHED();
+        break;
+    }
+
+    SetHostScanResult(*builder.Build());
+  }
+
+  void SetHostScanResult(const HostScanCacheEntry& entry) {
+    test_timer_factory_->set_tether_network_guid_for_next_timer(
+        entry.tether_network_guid);
+    host_scan_cache_->SetHostScanResult(entry);
+    expected_cache_->SetHostScanResult(entry);
+  }
+
+  void RemoveHostScanResult(const std::string& tether_network_guid) {
+    host_scan_cache_->RemoveHostScanResult(tether_network_guid);
+    expected_cache_->RemoveHostScanResult(tether_network_guid);
+  }
+
+  void ClearCacheExceptForActiveHost() {
+    host_scan_cache_->ClearCacheExceptForActiveHost();
+    expected_cache_->ClearCacheExceptForActiveHost();
+  }
+
+  bool HasConnectedToHost(const std::string& tether_network_guid) {
+    auto it =
+        std::find(has_connected_to_host_device_ids_.begin(),
+                  has_connected_to_host_device_ids_.end(), tether_network_guid);
+    return it != has_connected_to_host_device_ids_.end();
+  }
+
+  // Verifies that the information present in |expected_cache_| and
+  // |has_connected_to_host_device_ids_| mirrors what |host_scan_cache_| has set
+  // in NetworkStateHandler.
+  void VerifyCacheMatchesNetworkStack() {
+    for (auto& it : expected_cache_->cache()) {
+      const std::string tether_network_guid = it.first;
+      const HostScanCacheEntry& entry = it.second;
+
+      // Ensure that each entry in |expected_cache_| matches the
+      // corresponding entry in NetworkStateHandler.
+      const NetworkState* tether_network_state =
+          network_state_handler()->GetNetworkStateFromGuid(tether_network_guid);
+      ASSERT_TRUE(tether_network_state);
+      EXPECT_EQ(entry.device_name, tether_network_state->name());
+      EXPECT_EQ(entry.carrier, tether_network_state->carrier());
+      EXPECT_EQ(entry.battery_percentage,
+                tether_network_state->battery_percentage());
+      EXPECT_EQ(entry.signal_strength, tether_network_state->signal_strength());
+      EXPECT_EQ(entry.setup_required,
+                host_scan_cache_->DoesHostRequireSetup(tether_network_guid));
+      EXPECT_EQ(HasConnectedToHost(tether_network_guid),
+                tether_network_state->tether_has_connected_to_host());
+
+      // Ensure that each entry has an actively-running Timer.
+      auto timer_map_it =
+          test_timer_factory_->tether_network_guid_to_timer_map().begin();
+      EXPECT_NE(timer_map_it,
+                test_timer_factory_->tether_network_guid_to_timer_map().end());
+      EXPECT_TRUE(timer_map_it->second->IsRunning());
+    }
+  }
+
+  const base::test::ScopedTaskEnvironment scoped_task_environment_;
+
+  TestTimerFactory* test_timer_factory_;
+  std::unique_ptr<FakeActiveHost> fake_active_host_;
+  std::unique_ptr<NiceMock<MockTetherHostResponseRecorder>>
+      mock_tether_host_response_recorder_;
+  // TODO(hansberry): Use a fake for this when a real mapping scheme is created.
+  std::unique_ptr<DeviceIdTetherNetworkGuidMap>
+      device_id_tether_network_guid_map_;
+
+  std::vector<std::string> has_connected_to_host_device_ids_;
+  std::unique_ptr<FakeHostScanCache> expected_cache_;
+
+  std::unique_ptr<MasterHostScanCache> host_scan_cache_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MasterHostScanCacheTest);
+};
+
+TEST_F(MasterHostScanCacheTest, TestSetScanResultsAndLetThemExpire) {
+  SetCacheScanResultForDeviceIndex(0);
+  EXPECT_EQ(1u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  SetCacheScanResultForDeviceIndex(1);
+  EXPECT_EQ(2u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  SetCacheScanResultForDeviceIndex(2);
+  EXPECT_EQ(3u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  SetCacheScanResultForDeviceIndex(3);
+  EXPECT_EQ(4u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  FireTimer(kTetherGuid0);
+  EXPECT_EQ(3u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  FireTimer(kTetherGuid1);
+  EXPECT_EQ(2u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  FireTimer(kTetherGuid2);
+  EXPECT_EQ(1u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  FireTimer(kTetherGuid3);
+  EXPECT_TRUE(expected_cache_->empty());
+  VerifyCacheMatchesNetworkStack();
+}
+
+TEST_F(MasterHostScanCacheTest, TestSetScanResultThenUpdateAndRemove) {
+  SetCacheScanResultForDeviceIndex(0);
+  EXPECT_EQ(1u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  // Change the fields for tether network with GUID |kTetherGuid0| to the
+  // fields corresponding to |kTetherGuid1|.
+  SetHostScanResult(*HostScanCacheEntry::Builder()
+                         .SetTetherNetworkGuid(kTetherGuid0)
+                         .SetDeviceName(kTetherDeviceName0)
+                         .SetCarrier(kTetherCarrier1)
+                         .SetBatteryPercentage(kTetherBatteryPercentage1)
+                         .SetSignalStrength(kTetherSignalStrength1)
+                         .SetSetupRequired(kTetherSetupRequired1)
+                         .Build());
+  EXPECT_EQ(1u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  // Now, remove that result.
+  RemoveHostScanResult(kTetherGuid0);
+  EXPECT_TRUE(expected_cache_->empty());
+  VerifyCacheMatchesNetworkStack();
+}
+
+TEST_F(MasterHostScanCacheTest, TestSetScanResult_SetActiveHost_ThenClear) {
+  SetCacheScanResultForDeviceIndex(0);
+  EXPECT_EQ(1u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  SetCacheScanResultForDeviceIndex(1);
+  EXPECT_EQ(2u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  SetCacheScanResultForDeviceIndex(2);
+  EXPECT_EQ(3u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  // Now, set the active host to be the device 0.
+  SetActiveHost(kTetherGuid0);
+
+  // Clear the cache except for the active host.
+  ClearCacheExceptForActiveHost();
+  EXPECT_EQ(1u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  // Attempt to remove the active host. This operation should fail since
+  // removing the active host from the cache is not allowed.
+  RemoveHostScanResult(kTetherGuid0);
+  EXPECT_EQ(1u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  // Fire the timer for the active host. Likewise, this should not result in the
+  // cache entry being removed.
+  FireTimer(kTetherGuid0);
+  EXPECT_EQ(1u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  // Now, unset the active host.
+  SetActiveHost("");
+
+  // Removing the device should now succeed.
+  RemoveHostScanResult(kTetherGuid0);
+  EXPECT_TRUE(expected_cache_->empty());
+  VerifyCacheMatchesNetworkStack();
+}
+
+TEST_F(MasterHostScanCacheTest, TestHasConnectedToHost) {
+  // Before the test starts, set device 0 as having already connected.
+  SetHasConnectedToHost(kTetherGuid0);
+
+  SetCacheScanResultForDeviceIndex(0);
+  EXPECT_EQ(1u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  SetCacheScanResultForDeviceIndex(1);
+  EXPECT_EQ(2u, expected_cache_->size());
+  VerifyCacheMatchesNetworkStack();
+
+  // Simulate a connection to device 1.
+  SetActiveHost(kTetherGuid1);
+  SetHasConnectedToHost(kTetherGuid1);
+  VerifyCacheMatchesNetworkStack();
+}
+
+}  // namespace tether
+
+}  // namespace chromeos
diff --git a/chromeos/components/tether/network_connection_handler_tether_delegate_unittest.cc b/chromeos/components/tether/network_connection_handler_tether_delegate_unittest.cc
index aac1503..42d9b91 100644
--- a/chromeos/components/tether/network_connection_handler_tether_delegate_unittest.cc
+++ b/chromeos/components/tether/network_connection_handler_tether_delegate_unittest.cc
@@ -87,15 +87,7 @@
 
 class MockTetherDisconnector : public TetherDisconnector {
  public:
-  MockTetherDisconnector()
-      : TetherDisconnector(nullptr /* network_connection_handler */,
-                           nullptr /* network_state_handler */,
-                           nullptr /* active_host */,
-                           nullptr /* ble_connection_manager */,
-                           nullptr /* network_configuration_remover */,
-                           nullptr /* tether_connector */,
-                           nullptr /* device_id_tether_network_guid_map */,
-                           nullptr /* tether_host_fetcher */) {}
+  MockTetherDisconnector() : TetherDisconnector() {}
   ~MockTetherDisconnector() override {}
 
   MOCK_METHOD3(
diff --git a/chromeos/components/tether/pref_names.cc b/chromeos/components/tether/pref_names.cc
index 1e9b0cb..387aa2c 100644
--- a/chromeos/components/tether/pref_names.cc
+++ b/chromeos/components/tether/pref_names.cc
@@ -24,6 +24,9 @@
 
 const char kWifiNetworkGuid[] = "tether.wifi_network_id";
 
+const char kDisconnectingWifiNetworkGuid[] =
+    "tether.disconnecting_wifi_network_id";
+
 }  // namespace prefs
 
 }  // namespace tether
diff --git a/chromeos/components/tether/pref_names.h b/chromeos/components/tether/pref_names.h
index fa81731..9b77277 100644
--- a/chromeos/components/tether/pref_names.h
+++ b/chromeos/components/tether/pref_names.h
@@ -39,6 +39,17 @@
 // value at this key is "".
 extern const char kWifiNetworkGuid[];
 
+// The Wi-Fi network GUID that is currently being disconnected. When
+// disconnecting under normal circumstances, this value is set when a
+// disconnection is initiated and is cleared when a disconnection completes.
+// However, when a disconnection is triggered by the user logging out, the
+// disconnection flow cannot complete before Chrome shuts down (due to the
+// asynchronous nature of the network stack), so this GUID remains in prefs.
+// When the Tether component starts up again (the next time the user logs in),
+// this GUID is fetched, the associated network configuration is removed, and
+// the GUID is cleared from prefs.
+extern const char kDisconnectingWifiNetworkGuid[];
+
 }  // namespace prefs
 
 }  // namespace tether
diff --git a/chromeos/components/tether/tether_connector_unittest.cc b/chromeos/components/tether/tether_connector_unittest.cc
index 1398d2a..31e1755 100644
--- a/chromeos/components/tether/tether_connector_unittest.cc
+++ b/chromeos/components/tether/tether_connector_unittest.cc
@@ -202,9 +202,15 @@
     network_state_handler()->AddTetherNetworkState(
         tether_network_guid, device_name, carrier, battery_percentage,
         signal_strength, has_connected_to_host);
-    fake_host_scan_cache_->SetHostScanResult(tether_network_guid, device_name,
-                                             carrier, battery_percentage,
-                                             signal_strength, setup_required);
+    fake_host_scan_cache_->SetHostScanResult(
+        *HostScanCacheEntry::Builder()
+             .SetTetherNetworkGuid(tether_network_guid)
+             .SetDeviceName(device_name)
+             .SetCarrier(carrier)
+             .SetBatteryPercentage(battery_percentage)
+             .SetSignalStrength(signal_strength)
+             .SetSetupRequired(setup_required)
+             .Build());
   }
 
   void SuccessfullyJoinWifiNetwork() {
diff --git a/chromeos/components/tether/tether_disconnector.cc b/chromeos/components/tether/tether_disconnector.cc
deleted file mode 100644
index 65f8cef..0000000
--- a/chromeos/components/tether/tether_disconnector.cc
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromeos/components/tether/tether_disconnector.h"
-
-#include "base/values.h"
-#include "chromeos/components/tether/active_host.h"
-#include "chromeos/components/tether/device_id_tether_network_guid_map.h"
-#include "chromeos/components/tether/network_configuration_remover.h"
-#include "chromeos/components/tether/tether_connector.h"
-#include "chromeos/components/tether/tether_host_fetcher.h"
-#include "chromeos/network/network_connection_handler.h"
-#include "chromeos/network/network_state.h"
-#include "chromeos/network/network_state_handler.h"
-#include "components/proximity_auth/logging/logging.h"
-
-namespace chromeos {
-
-namespace tether {
-
-TetherDisconnector::TetherDisconnector(
-    NetworkConnectionHandler* network_connection_handler,
-    NetworkStateHandler* network_state_handler,
-    ActiveHost* active_host,
-    BleConnectionManager* ble_connection_manager,
-    NetworkConfigurationRemover* network_configuration_remover,
-    TetherConnector* tether_connector,
-    DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map,
-    TetherHostFetcher* tether_host_fetcher)
-    : network_connection_handler_(network_connection_handler),
-      network_state_handler_(network_state_handler),
-      active_host_(active_host),
-      ble_connection_manager_(ble_connection_manager),
-      network_configuration_remover_(network_configuration_remover),
-      tether_connector_(tether_connector),
-      device_id_tether_network_guid_map_(device_id_tether_network_guid_map),
-      tether_host_fetcher_(tether_host_fetcher),
-      weak_ptr_factory_(this) {}
-
-TetherDisconnector::~TetherDisconnector() {
-  if (disconnect_tethering_operation_)
-    disconnect_tethering_operation_->RemoveObserver(this);
-}
-
-void TetherDisconnector::DisconnectFromNetwork(
-    const std::string& tether_network_guid,
-    const base::Closure& success_callback,
-    const network_handler::StringResultCallback& error_callback) {
-  DCHECK(!tether_network_guid.empty());
-
-  ActiveHost::ActiveHostStatus status = active_host_->GetActiveHostStatus();
-  std::string active_tether_network_guid = active_host_->GetTetherNetworkGuid();
-  std::string active_wifi_network_guid = active_host_->GetWifiNetworkGuid();
-
-  if (status == ActiveHost::ActiveHostStatus::DISCONNECTED) {
-    PA_LOG(ERROR) << "Disconnect requested for Tether network with GUID "
-                  << tether_network_guid << ", but no device is connected.";
-    error_callback.Run(NetworkConnectionHandler::kErrorNotConnected);
-    return;
-  }
-
-  if (tether_network_guid != active_tether_network_guid) {
-    PA_LOG(ERROR) << "Disconnect requested for Tether network with GUID "
-                  << tether_network_guid << ", but that device is not the "
-                  << "active host.";
-    error_callback.Run(NetworkConnectionHandler::kErrorNotConnected);
-    return;
-  }
-
-  if (status == ActiveHost::ActiveHostStatus::CONNECTING) {
-    // Note: CancelConnectionAttempt() internally sets the active host to be
-    // disconnected.
-    if (tether_connector_->CancelConnectionAttempt(tether_network_guid)) {
-      PA_LOG(INFO) << "Disconnect requested for Tether network with GUID "
-                   << tether_network_guid << ", which had not yet connected. "
-                   << "Canceled in-progress connection attempt.";
-      success_callback.Run();
-      return;
-    }
-
-    PA_LOG(ERROR) << "Disconnect requested for Tether network with GUID "
-                  << tether_network_guid << " (not yet connected), but "
-                  << "canceling connection attempt failed.";
-    error_callback.Run(NetworkConnectionHandler::kErrorDisconnectFailed);
-    return;
-  }
-
-  DCHECK(!active_wifi_network_guid.empty());
-  DCHECK(!disconnect_tethering_operation_);
-  DisconnectActiveWifiConnection(tether_network_guid, active_wifi_network_guid,
-                                 success_callback, error_callback);
-}
-
-void TetherDisconnector::DisconnectActiveWifiConnection(
-    const std::string& tether_network_guid,
-    const std::string& wifi_network_guid,
-    const base::Closure& success_callback,
-    const network_handler::StringResultCallback& error_callback) {
-  // First, disconnect the active host so that the user gets visual indication
-  // that the disconnection is in progress as quickly as possible.
-  // TODO(hansberry): This will result in the Tether network becoming
-  // disconnected, but the Wi-Fi network will still be connected until the
-  // DisconnectNetwork() call below completes. This will result in a jarring UI
-  // transition which needs to be fixed.
-  active_host_->SetActiveHostDisconnected();
-
-  const NetworkState* wifi_network_state =
-      network_state_handler_->GetNetworkStateFromGuid(wifi_network_guid);
-  if (wifi_network_state) {
-    network_connection_handler_->DisconnectNetwork(
-        wifi_network_state->path(),
-        base::Bind(&TetherDisconnector::OnSuccessfulWifiDisconnect,
-                   weak_ptr_factory_.GetWeakPtr(), wifi_network_guid,
-                   success_callback, error_callback),
-        base::Bind(&TetherDisconnector::OnFailedWifiDisconnect,
-                   weak_ptr_factory_.GetWeakPtr(), wifi_network_guid,
-                   success_callback, error_callback));
-  } else {
-    PA_LOG(ERROR) << "Wi-Fi NetworkState for GUID " << wifi_network_guid << " "
-                  << "was not registered. Cannot disconnect.";
-    error_callback.Run(NetworkConnectionHandler::kErrorDisconnectFailed);
-  }
-
-  // In addition to disconnecting from the Wi-Fi network, this device must also
-  // send a DisconnectTetheringRequest to the tether host so that it can shut
-  // down its Wi-Fi hotspot if it is no longer in use.
-  const std::string device_id =
-      device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid(
-          tether_network_guid);
-  tether_host_fetcher_->FetchTetherHost(
-      device_id, base::Bind(&TetherDisconnector::OnTetherHostFetched,
-                            weak_ptr_factory_.GetWeakPtr(), device_id));
-}
-
-void TetherDisconnector::OnOperationFinished(const std::string& device_id,
-                                             bool success) {
-  if (success) {
-    PA_LOG(INFO) << "Successfully sent DisconnectTetheringRequest to device "
-                 << "with ID "
-                 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id);
-  } else {
-    PA_LOG(ERROR) << "Failed to send DisconnectTetheringRequest to device "
-                  << "with ID "
-                  << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(
-                         device_id);
-  }
-
-  // Regardless of success/failure, unregister as a listener and delete the
-  // operation.
-  disconnect_tethering_operation_->RemoveObserver(this);
-  disconnect_tethering_operation_.reset();
-}
-
-void TetherDisconnector::OnSuccessfulWifiDisconnect(
-    const std::string& wifi_network_guid,
-    const base::Closure& success_callback,
-    const network_handler::StringResultCallback& error_callback) {
-  PA_LOG(INFO) << "Successfully disconnected from Wi-Fi network with GUID "
-               << wifi_network_guid << ".";
-  CleanUpAfterWifiDisconnection(true /* success */, wifi_network_guid,
-                                success_callback, error_callback);
-}
-
-void TetherDisconnector::OnFailedWifiDisconnect(
-    const std::string& wifi_network_guid,
-    const base::Closure& success_callback,
-    const network_handler::StringResultCallback& error_callback,
-    const std::string& error_name,
-    std::unique_ptr<base::DictionaryValue> error_data) {
-  PA_LOG(ERROR) << "Failed to disconnect from Wi-Fi network with GUID "
-                << wifi_network_guid << ". Error name: " << error_name;
-  CleanUpAfterWifiDisconnection(false /* success */, wifi_network_guid,
-                                success_callback, error_callback);
-}
-
-void TetherDisconnector::CleanUpAfterWifiDisconnection(
-    bool success,
-    const std::string& wifi_network_guid,
-    const base::Closure& success_callback,
-    const network_handler::StringResultCallback& error_callback) {
-  if (success)
-    success_callback.Run();
-  else
-    error_callback.Run(NetworkConnectionHandler::kErrorDisconnectFailed);
-
-  network_configuration_remover_->RemoveNetworkConfiguration(wifi_network_guid);
-}
-
-void TetherDisconnector::OnTetherHostFetched(
-    const std::string& device_id,
-    std::unique_ptr<cryptauth::RemoteDevice> tether_host) {
-  if (!tether_host) {
-    PA_LOG(ERROR) << "Could not fetch device with ID "
-                  << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id)
-                  << ". Unable to send DisconnectTetheringRequest.";
-    return;
-  }
-
-  disconnect_tethering_operation_ =
-      DisconnectTetheringOperation::Factory::NewInstance(
-          *tether_host, ble_connection_manager_);
-
-  // Start the operation; OnOperationFinished() will be called when finished.
-  disconnect_tethering_operation_->AddObserver(this);
-  disconnect_tethering_operation_->Initialize();
-}
-
-}  // namespace tether
-
-}  // namespace chromeos
diff --git a/chromeos/components/tether/tether_disconnector.h b/chromeos/components/tether/tether_disconnector.h
index b620b92a..39381e42 100644
--- a/chromeos/components/tether/tether_disconnector.h
+++ b/chromeos/components/tether/tether_disconnector.h
@@ -5,9 +5,7 @@
 #ifndef CHROMEOS_COMPONENTS_TETHER_TETHER_DISCONNECTOR_H_
 #define CHROMEOS_COMPONENTS_TETHER_TETHER_DISCONNECTOR_H_
 
-#include <memory>
 #include <string>
-#include <unordered_map>
 
 #include "base/callback_forward.h"
 #include "base/macros.h"
@@ -15,84 +13,26 @@
 #include "chromeos/components/tether/disconnect_tethering_operation.h"
 #include "chromeos/network/network_handler_callbacks.h"
 
-namespace base {
-class DictionaryValue;
-}
-
 namespace chromeos {
 
-class NetworkConnectionHandler;
-class NetworkStateHandler;
-
 namespace tether {
 
-class ActiveHost;
-class BleConnectionManager;
-class DeviceIdTetherNetworkGuidMap;
-class NetworkConfigurationRemover;
-class TetherConnector;
-class TetherHostFetcher;
-
-class TetherDisconnector : public DisconnectTetheringOperation::Observer {
+// Disconnects from an active Tether connection.
+class TetherDisconnector {
  public:
-  TetherDisconnector(
-      NetworkConnectionHandler* network_connection_handler,
-      NetworkStateHandler* network_state_handler,
-      ActiveHost* active_host,
-      BleConnectionManager* ble_connection_manager,
-      NetworkConfigurationRemover* network_configuration_remover,
-      TetherConnector* tether_connector,
-      DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map,
-      TetherHostFetcher* tether_host_fetcher);
-  virtual ~TetherDisconnector();
+  TetherDisconnector() {}
+  virtual ~TetherDisconnector() {}
 
+  // Disconnects from the network with GUID |tether_network_guid|. This GUID
+  // must correspond to an active (i.e., connecting/connected) Tether network.
+  // If disconnection fails, |error_callback| is invoked with a
+  // NetworkConnectionHandler error value.
   virtual void DisconnectFromNetwork(
       const std::string& tether_network_guid,
       const base::Closure& success_callback,
-      const network_handler::StringResultCallback& error_callback);
-
-  // DisconnectTetheringOperation::Observer:
-  void OnOperationFinished(const std::string& device_id, bool success) override;
+      const network_handler::StringResultCallback& error_callback) = 0;
 
  private:
-  friend class TetherDisconnectorTest;
-
-  void DisconnectActiveWifiConnection(
-      const std::string& tether_network_guid,
-      const std::string& wifi_network_guid,
-      const base::Closure& success_callback,
-      const network_handler::StringResultCallback& error_callback);
-  void OnSuccessfulWifiDisconnect(
-      const std::string& wifi_network_guid,
-      const base::Closure& success_callback,
-      const network_handler::StringResultCallback& error_callback);
-  void OnFailedWifiDisconnect(
-      const std::string& wifi_network_guid,
-      const base::Closure& success_callback,
-      const network_handler::StringResultCallback& error_callback,
-      const std::string& error_name,
-      std::unique_ptr<base::DictionaryValue> error_data);
-  void CleanUpAfterWifiDisconnection(
-      bool success,
-      const std::string& wifi_network_guid,
-      const base::Closure& success_callback,
-      const network_handler::StringResultCallback& error_callback);
-  void OnTetherHostFetched(
-      const std::string& device_id,
-      std::unique_ptr<cryptauth::RemoteDevice> tether_host);
-
-  NetworkConnectionHandler* network_connection_handler_;
-  NetworkStateHandler* network_state_handler_;
-  ActiveHost* active_host_;
-  BleConnectionManager* ble_connection_manager_;
-  NetworkConfigurationRemover* network_configuration_remover_;
-  TetherConnector* tether_connector_;
-  DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map_;
-  TetherHostFetcher* tether_host_fetcher_;
-
-  std::unique_ptr<DisconnectTetheringOperation> disconnect_tethering_operation_;
-  base::WeakPtrFactory<TetherDisconnector> weak_ptr_factory_;
-
   DISALLOW_COPY_AND_ASSIGN(TetherDisconnector);
 };
 
diff --git a/chromeos/components/tether/tether_disconnector_impl.cc b/chromeos/components/tether/tether_disconnector_impl.cc
new file mode 100644
index 0000000..0814144
--- /dev/null
+++ b/chromeos/components/tether/tether_disconnector_impl.cc
@@ -0,0 +1,260 @@
+// 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 "chromeos/components/tether/tether_disconnector_impl.h"
+
+#include "base/values.h"
+#include "chromeos/components/tether/active_host.h"
+#include "chromeos/components/tether/device_id_tether_network_guid_map.h"
+#include "chromeos/components/tether/network_configuration_remover.h"
+#include "chromeos/components/tether/pref_names.h"
+#include "chromeos/components/tether/tether_connector.h"
+#include "chromeos/components/tether/tether_host_fetcher.h"
+#include "chromeos/network/network_connection_handler.h"
+#include "chromeos/network/network_state.h"
+#include "chromeos/network/network_state_handler.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/pref_service.h"
+#include "components/proximity_auth/logging/logging.h"
+
+namespace chromeos {
+
+namespace tether {
+
+namespace {
+
+void OnDisconnectError(const std::string& error_name) {
+  PA_LOG(WARNING) << "Error disconnecting from Tether network during shutdown; "
+                  << "Error name: " << error_name;
+}
+
+}  // namespace
+
+// static
+void TetherDisconnectorImpl::RegisterPrefs(PrefRegistrySimple* registry) {
+  registry->RegisterStringPref(prefs::kDisconnectingWifiNetworkGuid, "");
+}
+
+TetherDisconnectorImpl::TetherDisconnectorImpl(
+    NetworkConnectionHandler* network_connection_handler,
+    NetworkStateHandler* network_state_handler,
+    ActiveHost* active_host,
+    BleConnectionManager* ble_connection_manager,
+    NetworkConfigurationRemover* network_configuration_remover,
+    TetherConnector* tether_connector,
+    DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map,
+    TetherHostFetcher* tether_host_fetcher,
+    PrefService* pref_service)
+    : network_connection_handler_(network_connection_handler),
+      network_state_handler_(network_state_handler),
+      active_host_(active_host),
+      ble_connection_manager_(ble_connection_manager),
+      network_configuration_remover_(network_configuration_remover),
+      tether_connector_(tether_connector),
+      device_id_tether_network_guid_map_(device_id_tether_network_guid_map),
+      tether_host_fetcher_(tether_host_fetcher),
+      pref_service_(pref_service),
+      weak_ptr_factory_(this) {
+  std::string disconnecting_wifi_guid_from_previous_session =
+      pref_service_->GetString(prefs::kDisconnectingWifiNetworkGuid);
+  if (!disconnecting_wifi_guid_from_previous_session.empty()) {
+    // If a previous disconnection attempt was aborted before it could be fully
+    // completed, clean up the leftover network configuration.
+    network_configuration_remover_->RemoveNetworkConfiguration(
+        disconnecting_wifi_guid_from_previous_session);
+    pref_service_->ClearPref(prefs::kDisconnectingWifiNetworkGuid);
+  }
+}
+
+TetherDisconnectorImpl::~TetherDisconnectorImpl() {
+  if (disconnect_tethering_operation_)
+    disconnect_tethering_operation_->RemoveObserver(this);
+
+  std::string active_tether_guid = active_host_->GetTetherNetworkGuid();
+  if (!active_tether_guid.empty()) {
+    PA_LOG(INFO) << "There was an active Tether connection during Tether "
+                 << "shutdown. Initiating disconnection from network with GUID "
+                 << "\"" << active_tether_guid << "\"";
+    DisconnectFromNetwork(active_tether_guid, base::Bind(&base::DoNothing),
+                          base::Bind(&OnDisconnectError));
+  }
+}
+
+void TetherDisconnectorImpl::DisconnectFromNetwork(
+    const std::string& tether_network_guid,
+    const base::Closure& success_callback,
+    const network_handler::StringResultCallback& error_callback) {
+  DCHECK(!tether_network_guid.empty());
+
+  ActiveHost::ActiveHostStatus status = active_host_->GetActiveHostStatus();
+  std::string active_tether_network_guid = active_host_->GetTetherNetworkGuid();
+  std::string active_wifi_network_guid = active_host_->GetWifiNetworkGuid();
+
+  if (status == ActiveHost::ActiveHostStatus::DISCONNECTED) {
+    PA_LOG(ERROR) << "Disconnect requested for Tether network with GUID "
+                  << tether_network_guid << ", but no device is connected.";
+    error_callback.Run(NetworkConnectionHandler::kErrorNotConnected);
+    return;
+  }
+
+  if (tether_network_guid != active_tether_network_guid) {
+    PA_LOG(ERROR) << "Disconnect requested for Tether network with GUID "
+                  << tether_network_guid << ", but that device is not the "
+                  << "active host.";
+    error_callback.Run(NetworkConnectionHandler::kErrorNotConnected);
+    return;
+  }
+
+  if (status == ActiveHost::ActiveHostStatus::CONNECTING) {
+    // Note: CancelConnectionAttempt() internally sets the active host to be
+    // disconnected.
+    if (tether_connector_->CancelConnectionAttempt(tether_network_guid)) {
+      PA_LOG(INFO) << "Disconnect requested for Tether network with GUID "
+                   << tether_network_guid << ", which had not yet connected. "
+                   << "Canceled in-progress connection attempt.";
+      success_callback.Run();
+      return;
+    }
+
+    PA_LOG(ERROR) << "Disconnect requested for Tether network with GUID "
+                  << tether_network_guid << " (not yet connected), but "
+                  << "canceling connection attempt failed.";
+    error_callback.Run(NetworkConnectionHandler::kErrorDisconnectFailed);
+    return;
+  }
+
+  DCHECK(!active_wifi_network_guid.empty());
+  DCHECK(!disconnect_tethering_operation_);
+  DisconnectActiveWifiConnection(tether_network_guid, active_wifi_network_guid,
+                                 success_callback, error_callback);
+}
+
+void TetherDisconnectorImpl::DisconnectActiveWifiConnection(
+    const std::string& tether_network_guid,
+    const std::string& wifi_network_guid,
+    const base::Closure& success_callback,
+    const network_handler::StringResultCallback& error_callback) {
+  // First, disconnect the active host so that the user gets visual indication
+  // that the disconnection is in progress as quickly as possible.
+  // TODO(hansberry): This will result in the Tether network becoming
+  // disconnected, but the Wi-Fi network will still be connected until the
+  // DisconnectNetwork() call below completes. This will result in a jarring UI
+  // transition which needs to be fixed.
+  active_host_->SetActiveHostDisconnected();
+
+  // Before starting disconnection, log the disconnecting Wi-Fi GUID to prefs.
+  // Under normal circumstances, the GUID will be cleared as part of
+  // CleanUpAfterWifiDisconnection(). However, when the user logs out,
+  // this TetherDisconnectorImpl instance will be deleted before one of the
+  // callbacks passed below to DisconnectNetwork() can be called, and the
+  // GUID will remain in prefs until the next time the user logs in, at which
+  // time the associated network configuration can be removed.
+  pref_service_->Set(prefs::kDisconnectingWifiNetworkGuid,
+                     base::Value(wifi_network_guid));
+
+  const NetworkState* wifi_network_state =
+      network_state_handler_->GetNetworkStateFromGuid(wifi_network_guid);
+  if (wifi_network_state) {
+    network_connection_handler_->DisconnectNetwork(
+        wifi_network_state->path(),
+        base::Bind(&TetherDisconnectorImpl::OnSuccessfulWifiDisconnect,
+                   weak_ptr_factory_.GetWeakPtr(), wifi_network_guid,
+                   success_callback, error_callback),
+        base::Bind(&TetherDisconnectorImpl::OnFailedWifiDisconnect,
+                   weak_ptr_factory_.GetWeakPtr(), wifi_network_guid,
+                   success_callback, error_callback));
+  } else {
+    PA_LOG(ERROR) << "Wi-Fi NetworkState for GUID " << wifi_network_guid << " "
+                  << "was not registered. Cannot disconnect.";
+    error_callback.Run(NetworkConnectionHandler::kErrorDisconnectFailed);
+  }
+
+  // In addition to disconnecting from the Wi-Fi network, this device must also
+  // send a DisconnectTetheringRequest to the tether host so that it can shut
+  // down its Wi-Fi hotspot if it is no longer in use.
+  const std::string device_id =
+      device_id_tether_network_guid_map_->GetDeviceIdForTetherNetworkGuid(
+          tether_network_guid);
+  tether_host_fetcher_->FetchTetherHost(
+      device_id, base::Bind(&TetherDisconnectorImpl::OnTetherHostFetched,
+                            weak_ptr_factory_.GetWeakPtr(), device_id));
+}
+
+void TetherDisconnectorImpl::OnOperationFinished(const std::string& device_id,
+                                                 bool success) {
+  if (success) {
+    PA_LOG(INFO) << "Successfully sent DisconnectTetheringRequest to device "
+                 << "with ID "
+                 << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id);
+  } else {
+    PA_LOG(ERROR) << "Failed to send DisconnectTetheringRequest to device "
+                  << "with ID "
+                  << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(
+                         device_id);
+  }
+
+  // Regardless of success/failure, unregister as a listener and delete the
+  // operation.
+  disconnect_tethering_operation_->RemoveObserver(this);
+  disconnect_tethering_operation_.reset();
+}
+
+void TetherDisconnectorImpl::OnSuccessfulWifiDisconnect(
+    const std::string& wifi_network_guid,
+    const base::Closure& success_callback,
+    const network_handler::StringResultCallback& error_callback) {
+  PA_LOG(INFO) << "Successfully disconnected from Wi-Fi network with GUID "
+               << wifi_network_guid << ".";
+  CleanUpAfterWifiDisconnection(true /* success */, wifi_network_guid,
+                                success_callback, error_callback);
+}
+
+void TetherDisconnectorImpl::OnFailedWifiDisconnect(
+    const std::string& wifi_network_guid,
+    const base::Closure& success_callback,
+    const network_handler::StringResultCallback& error_callback,
+    const std::string& error_name,
+    std::unique_ptr<base::DictionaryValue> error_data) {
+  PA_LOG(ERROR) << "Failed to disconnect from Wi-Fi network with GUID "
+                << wifi_network_guid << ". Error name: " << error_name;
+  CleanUpAfterWifiDisconnection(false /* success */, wifi_network_guid,
+                                success_callback, error_callback);
+}
+
+void TetherDisconnectorImpl::CleanUpAfterWifiDisconnection(
+    bool success,
+    const std::string& wifi_network_guid,
+    const base::Closure& success_callback,
+    const network_handler::StringResultCallback& error_callback) {
+  network_configuration_remover_->RemoveNetworkConfiguration(wifi_network_guid);
+  pref_service_->ClearPref(prefs::kDisconnectingWifiNetworkGuid);
+
+  if (success)
+    success_callback.Run();
+  else
+    error_callback.Run(NetworkConnectionHandler::kErrorDisconnectFailed);
+}
+
+void TetherDisconnectorImpl::OnTetherHostFetched(
+    const std::string& device_id,
+    std::unique_ptr<cryptauth::RemoteDevice> tether_host) {
+  if (!tether_host) {
+    PA_LOG(ERROR) << "Could not fetch device with ID "
+                  << cryptauth::RemoteDevice::TruncateDeviceIdForLogs(device_id)
+                  << ". Unable to send DisconnectTetheringRequest.";
+    return;
+  }
+
+  disconnect_tethering_operation_ =
+      DisconnectTetheringOperation::Factory::NewInstance(
+          *tether_host, ble_connection_manager_);
+
+  // Start the operation; OnOperationFinished() will be called when finished.
+  disconnect_tethering_operation_->AddObserver(this);
+  disconnect_tethering_operation_->Initialize();
+}
+
+}  // namespace tether
+
+}  // namespace chromeos
diff --git a/chromeos/components/tether/tether_disconnector_impl.h b/chromeos/components/tether/tether_disconnector_impl.h
new file mode 100644
index 0000000..886e5336
--- /dev/null
+++ b/chromeos/components/tether/tether_disconnector_impl.h
@@ -0,0 +1,113 @@
+// 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 CHROMEOS_COMPONENTS_TETHER_TETHER_DISCONNECTOR_IMPL_H_
+#define CHROMEOS_COMPONENTS_TETHER_TETHER_DISCONNECTOR_IMPL_H_
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#include "base/callback_forward.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "chromeos/components/tether/disconnect_tethering_operation.h"
+#include "chromeos/components/tether/tether_disconnector.h"
+#include "chromeos/network/network_handler_callbacks.h"
+
+class PrefRegistrySimple;
+class PrefService;
+
+namespace base {
+class DictionaryValue;
+}
+
+namespace chromeos {
+
+class NetworkConnectionHandler;
+class NetworkStateHandler;
+
+namespace tether {
+
+class ActiveHost;
+class BleConnectionManager;
+class DeviceIdTetherNetworkGuidMap;
+class NetworkConfigurationRemover;
+class TetherConnector;
+class TetherHostFetcher;
+
+class TetherDisconnectorImpl : public TetherDisconnector,
+                               public DisconnectTetheringOperation::Observer {
+ public:
+  // Registers the prefs used by this class to the given |registry|.
+  static void RegisterPrefs(PrefRegistrySimple* registry);
+
+  TetherDisconnectorImpl(
+      NetworkConnectionHandler* network_connection_handler,
+      NetworkStateHandler* network_state_handler,
+      ActiveHost* active_host,
+      BleConnectionManager* ble_connection_manager,
+      NetworkConfigurationRemover* network_configuration_remover,
+      TetherConnector* tether_connector,
+      DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map,
+      TetherHostFetcher* tether_host_fetcher,
+      PrefService* pref_service);
+  ~TetherDisconnectorImpl() override;
+
+  void DisconnectFromNetwork(
+      const std::string& tether_network_guid,
+      const base::Closure& success_callback,
+      const network_handler::StringResultCallback& error_callback) override;
+
+  // DisconnectTetheringOperation::Observer:
+  void OnOperationFinished(const std::string& device_id, bool success) override;
+
+ private:
+  friend class TetherDisconnectorImplTest;
+
+  void DisconnectActiveWifiConnection(
+      const std::string& tether_network_guid,
+      const std::string& wifi_network_guid,
+      const base::Closure& success_callback,
+      const network_handler::StringResultCallback& error_callback);
+  void OnSuccessfulWifiDisconnect(
+      const std::string& wifi_network_guid,
+      const base::Closure& success_callback,
+      const network_handler::StringResultCallback& error_callback);
+  void OnFailedWifiDisconnect(
+      const std::string& wifi_network_guid,
+      const base::Closure& success_callback,
+      const network_handler::StringResultCallback& error_callback,
+      const std::string& error_name,
+      std::unique_ptr<base::DictionaryValue> error_data);
+  void CleanUpAfterWifiDisconnection(
+      bool success,
+      const std::string& wifi_network_guid,
+      const base::Closure& success_callback,
+      const network_handler::StringResultCallback& error_callback);
+  void OnTetherHostFetched(
+      const std::string& device_id,
+      std::unique_ptr<cryptauth::RemoteDevice> tether_host);
+
+  NetworkConnectionHandler* network_connection_handler_;
+  NetworkStateHandler* network_state_handler_;
+  ActiveHost* active_host_;
+  BleConnectionManager* ble_connection_manager_;
+  NetworkConfigurationRemover* network_configuration_remover_;
+  TetherConnector* tether_connector_;
+  DeviceIdTetherNetworkGuidMap* device_id_tether_network_guid_map_;
+  TetherHostFetcher* tether_host_fetcher_;
+  PrefService* pref_service_;
+
+  std::unique_ptr<DisconnectTetheringOperation> disconnect_tethering_operation_;
+  base::WeakPtrFactory<TetherDisconnectorImpl> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(TetherDisconnectorImpl);
+};
+
+}  // namespace tether
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_COMPONENTS_TETHER_TETHER_DISCONNECTOR_IMPL_H_
diff --git a/chromeos/components/tether/tether_disconnector_impl_unittest.cc b/chromeos/components/tether/tether_disconnector_impl_unittest.cc
new file mode 100644
index 0000000..ccd4c9f8
--- /dev/null
+++ b/chromeos/components/tether/tether_disconnector_impl_unittest.cc
@@ -0,0 +1,682 @@
+// 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 "chromeos/components/tether/tether_disconnector_impl.h"
+
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
+#include "chromeos/components/tether/connect_tethering_operation.h"
+#include "chromeos/components/tether/device_id_tether_network_guid_map.h"
+#include "chromeos/components/tether/fake_active_host.h"
+#include "chromeos/components/tether/fake_ble_connection_manager.h"
+#include "chromeos/components/tether/fake_network_configuration_remover.h"
+#include "chromeos/components/tether/fake_tether_host_fetcher.h"
+#include "chromeos/components/tether/fake_wifi_hotspot_connector.h"
+#include "chromeos/components/tether/mock_tether_host_response_recorder.h"
+#include "chromeos/components/tether/pref_names.h"
+#include "chromeos/components/tether/tether_connector.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/network/network_connection_handler.h"
+#include "chromeos/network/network_state.h"
+#include "chromeos/network/network_state_handler.h"
+#include "chromeos/network/network_state_test.h"
+#include "components/cryptauth/remote_device.h"
+#include "components/cryptauth/remote_device_test_util.h"
+#include "components/prefs/testing_pref_service.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
+
+namespace chromeos {
+
+namespace tether {
+
+namespace {
+
+const char kSuccessResult[] = "success";
+
+const char kWifiNetworkGuid[] = "wifiNetworkGuid";
+
+std::string CreateConnectedWifiConfigurationJsonString(
+    const std::string& wifi_network_guid) {
+  std::stringstream ss;
+  ss << "{"
+     << "  \"GUID\": \"" << wifi_network_guid << "\","
+     << "  \"Type\": \"" << shill::kTypeWifi << "\","
+     << "  \"State\": \"" << shill::kStateOnline << "\""
+     << "}";
+  return ss.str();
+}
+
+class TestNetworkConnectionHandler : public NetworkConnectionHandler {
+ public:
+  explicit TestNetworkConnectionHandler(base::Closure disconnect_callback)
+      : disconnect_callback_(disconnect_callback) {}
+  ~TestNetworkConnectionHandler() override {}
+
+  std::string last_disconnect_service_path() {
+    return last_disconnect_service_path_;
+  }
+
+  base::Closure last_disconnect_success_callback() {
+    return last_disconnect_success_callback_;
+  }
+
+  network_handler::ErrorCallback last_disconnect_error_callback() {
+    return last_disconnect_error_callback_;
+  }
+
+  // NetworkConnectionHandler:
+  void DisconnectNetwork(
+      const std::string& service_path,
+      const base::Closure& success_callback,
+      const network_handler::ErrorCallback& error_callback) override {
+    last_disconnect_service_path_ = service_path;
+    last_disconnect_success_callback_ = success_callback;
+    last_disconnect_error_callback_ = error_callback;
+
+    disconnect_callback_.Run();
+  }
+  void ConnectToNetwork(const std::string& service_path,
+                        const base::Closure& success_callback,
+                        const network_handler::ErrorCallback& error_callback,
+                        bool check_error_state) override {}
+  bool HasConnectingNetwork(const std::string& service_path) override {
+    return false;
+  }
+  bool HasPendingConnectRequest() override { return false; }
+  void Init(NetworkStateHandler* network_state_handler,
+            NetworkConfigurationHandler* network_configuration_handler,
+            ManagedNetworkConfigurationHandler*
+                managed_network_configuration_handler) override {}
+
+ private:
+  base::Closure disconnect_callback_;
+
+  std::string last_disconnect_service_path_;
+  base::Closure last_disconnect_success_callback_;
+  network_handler::ErrorCallback last_disconnect_error_callback_;
+};
+
+class TestTetherConnector : public TetherConnector {
+ public:
+  TestTetherConnector()
+      : TetherConnector(nullptr /* network_state_handler */,
+                        nullptr /* wifi_hotspot_connector */,
+                        nullptr /* active_host */,
+                        nullptr /* tether_host_fetcher */,
+                        nullptr /* connection_manager */,
+                        nullptr /* tether_host_response_recorder */,
+                        nullptr /* device_id_tether_network_guid_map */,
+                        nullptr /* host_scan_cache */,
+                        nullptr /* notification_presenter */),
+        should_cancel_successfully_(true) {}
+  ~TestTetherConnector() override {}
+
+  void set_should_cancel_successfully(bool should_cancel_successfully) {
+    should_cancel_successfully_ = should_cancel_successfully;
+  }
+
+  std::string last_canceled_tether_network_guid() {
+    return last_canceled_tether_network_guid_;
+  }
+
+  // TetherConnector:
+  bool CancelConnectionAttempt(
+      const std::string& tether_network_guid) override {
+    last_canceled_tether_network_guid_ = tether_network_guid;
+    return should_cancel_successfully_;
+  }
+
+ private:
+  bool should_cancel_successfully_;
+  std::string last_canceled_tether_network_guid_;
+};
+
+class FakeDisconnectTetheringOperation : public DisconnectTetheringOperation {
+ public:
+  FakeDisconnectTetheringOperation(
+      const cryptauth::RemoteDevice& device_to_connect,
+      BleConnectionManager* connection_manager)
+      : DisconnectTetheringOperation(device_to_connect, connection_manager) {}
+
+  ~FakeDisconnectTetheringOperation() override {}
+
+  void NotifyFinished(bool success) {
+    NotifyObserversOperationFinished(success);
+  }
+
+  cryptauth::RemoteDevice GetRemoteDevice() {
+    EXPECT_EQ(1u, remote_devices().size());
+    return remote_devices()[0];
+  }
+};
+
+class FakeDisconnectTetheringOperationFactory
+    : public DisconnectTetheringOperation::Factory {
+ public:
+  FakeDisconnectTetheringOperationFactory() {}
+  virtual ~FakeDisconnectTetheringOperationFactory() {}
+
+  std::vector<FakeDisconnectTetheringOperation*>& created_operations() {
+    return created_operations_;
+  }
+
+ protected:
+  // DisconnectTetheringOperation::Factory:
+  std::unique_ptr<DisconnectTetheringOperation> BuildInstance(
+      const cryptauth::RemoteDevice& device_to_connect,
+      BleConnectionManager* connection_manager) override {
+    FakeDisconnectTetheringOperation* operation =
+        new FakeDisconnectTetheringOperation(device_to_connect,
+                                             connection_manager);
+    created_operations_.push_back(operation);
+    return base::WrapUnique(operation);
+  }
+
+ private:
+  std::vector<FakeDisconnectTetheringOperation*> created_operations_;
+};
+
+}  // namespace
+
+class TetherDisconnectorImplTest : public NetworkStateTest {
+ public:
+  TetherDisconnectorImplTest()
+      : test_devices_(cryptauth::GenerateTestRemoteDevices(2u)) {}
+  ~TetherDisconnectorImplTest() override {}
+
+  void SetUp() override {
+    DBusThreadManager::Initialize();
+    NetworkStateTest::SetUp();
+
+    should_run_disconnect_callbacks_synchronously_ = true;
+    should_disconnect_successfully_ = true;
+
+    test_network_connection_handler_ =
+        base::WrapUnique(new TestNetworkConnectionHandler(base::Bind(
+            &TetherDisconnectorImplTest::OnNetworkConnectionManagerDisconnect,
+            base::Unretained(this))));
+    fake_active_host_ = base::MakeUnique<FakeActiveHost>();
+    fake_ble_connection_manager_ = base::MakeUnique<FakeBleConnectionManager>();
+    fake_network_configuration_remover_ =
+        base::MakeUnique<FakeNetworkConfigurationRemover>();
+    test_tether_connector_ = base::WrapUnique(new TestTetherConnector());
+    device_id_tether_network_guid_map_ =
+        base::MakeUnique<DeviceIdTetherNetworkGuidMap>();
+    fake_tether_host_fetcher_ = base::MakeUnique<FakeTetherHostFetcher>(
+        test_devices_, true /* synchronously_reply_with_results */);
+    test_pref_service_ = base::MakeUnique<TestingPrefServiceSimple>();
+
+    fake_operation_factory_ =
+        base::WrapUnique(new FakeDisconnectTetheringOperationFactory());
+    DisconnectTetheringOperation::Factory::SetInstanceForTesting(
+        fake_operation_factory_.get());
+
+    SetUpTetherNetworks();
+
+    TetherDisconnectorImpl::RegisterPrefs(test_pref_service_->registry());
+    tether_disconnector_ = base::MakeUnique<TetherDisconnectorImpl>(
+        test_network_connection_handler_.get(), network_state_handler(),
+        fake_active_host_.get(), fake_ble_connection_manager_.get(),
+        fake_network_configuration_remover_.get(), test_tether_connector_.get(),
+        device_id_tether_network_guid_map_.get(),
+        fake_tether_host_fetcher_.get(), test_pref_service_.get());
+  }
+
+  void TearDown() override {
+    tether_disconnector_.reset();
+    ShutdownNetworkState();
+    NetworkStateTest::TearDown();
+    DBusThreadManager::Shutdown();
+  }
+
+  std::string GetTetherNetworkGuid(const std::string& device_id) {
+    return device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId(
+        device_id);
+  }
+
+  void SetUpTetherNetworks() {
+    network_state_handler()->SetTetherTechnologyState(
+        NetworkStateHandler::TECHNOLOGY_ENABLED);
+
+    // Add a tether network corresponding to both of the test devices. These
+    // networks are expected to be added already before
+    // TetherDisconnectorImpl::DisconnectFromNetwork() is called.
+    network_state_handler()->AddTetherNetworkState(
+        GetTetherNetworkGuid(test_devices_[0].GetDeviceId()),
+        "TetherNetworkName1", "TetherNetworkCarrier1",
+        85 /* battery_percentage */, 75 /* signal_strength */,
+        true /* has_connected_to_host */);
+    network_state_handler()->AddTetherNetworkState(
+        GetTetherNetworkGuid(test_devices_[1].GetDeviceId()),
+        "TetherNetworkName2", "TetherNetworkCarrier2",
+        90 /* battery_percentage */, 50 /* signal_strength */,
+        true /* has_connected_to_host */);
+  }
+
+  void SimulateConnectionToWifiNetwork() {
+    wifi_service_path_ = ConfigureService(
+        CreateConnectedWifiConfigurationJsonString(kWifiNetworkGuid));
+    EXPECT_FALSE(wifi_service_path_.empty());
+  }
+
+  void SuccessCallback() { disconnection_result_ = kSuccessResult; }
+
+  void ErrorCallback(const std::string& error_name) {
+    disconnection_result_ = error_name;
+  }
+
+  void CallDisconnect(const std::string& tether_network_guid) {
+    tether_disconnector_->DisconnectFromNetwork(
+        tether_network_guid,
+        base::Bind(&TetherDisconnectorImplTest::SuccessCallback,
+                   base::Unretained(this)),
+        base::Bind(&TetherDisconnectorImplTest::ErrorCallback,
+                   base::Unretained(this)));
+  }
+
+  // This function is called by
+  // TestNetworkConnectionHandler::DisconnectFromNetwork().
+  void OnNetworkConnectionManagerDisconnect() {
+    EXPECT_EQ(wifi_service_path_,
+              test_network_connection_handler_->last_disconnect_service_path());
+
+    if (should_disconnect_successfully_) {
+      SetServiceProperty(wifi_service_path_, shill::kStateProperty,
+                         base::Value(shill::kStateIdle));
+    }
+
+    if (should_run_disconnect_callbacks_synchronously_) {
+      // Before the callbacks are invoked, the network configuration should not
+      // yet have been cleared, and the disconnecting GUID should still be in
+      // prefs.
+      EXPECT_TRUE(
+          fake_network_configuration_remover_->last_removed_wifi_network_guid()
+              .empty());
+      EXPECT_FALSE(GetDisconnectingWifiGuidFromPrefs().empty());
+
+      if (should_disconnect_successfully_) {
+        EXPECT_FALSE(
+            test_network_connection_handler_->last_disconnect_success_callback()
+                .is_null());
+        test_network_connection_handler_->last_disconnect_success_callback()
+            .Run();
+      } else {
+        EXPECT_FALSE(
+            test_network_connection_handler_->last_disconnect_error_callback()
+                .is_null());
+        network_handler::RunErrorCallback(
+            test_network_connection_handler_->last_disconnect_error_callback(),
+            wifi_service_path_,
+            NetworkConnectionHandler::kErrorDisconnectFailed,
+            "" /* error_detail */);
+      }
+
+      // Now that the callbacks have been invoked, both the network
+      // configuration and the disconnecting GUID should have cleared.
+      EXPECT_FALSE(
+          fake_network_configuration_remover_->last_removed_wifi_network_guid()
+              .empty());
+      EXPECT_TRUE(GetDisconnectingWifiGuidFromPrefs().empty());
+    }
+  }
+
+  std::string GetResultAndReset() {
+    std::string result;
+    result.swap(disconnection_result_);
+    return result;
+  }
+
+  std::string GetDisconnectingWifiGuidFromPrefs() {
+    return test_pref_service_->GetString(prefs::kDisconnectingWifiNetworkGuid);
+  }
+
+  const std::vector<cryptauth::RemoteDevice> test_devices_;
+  const base::MessageLoop message_loop_;
+
+  std::unique_ptr<TestNetworkConnectionHandler>
+      test_network_connection_handler_;
+  std::unique_ptr<FakeActiveHost> fake_active_host_;
+  std::unique_ptr<FakeBleConnectionManager> fake_ble_connection_manager_;
+  std::unique_ptr<FakeNetworkConfigurationRemover>
+      fake_network_configuration_remover_;
+  std::unique_ptr<TestTetherConnector> test_tether_connector_;
+  // TODO(hansberry): Use a fake for this when a real mapping scheme is created.
+  std::unique_ptr<DeviceIdTetherNetworkGuidMap>
+      device_id_tether_network_guid_map_;
+  std::unique_ptr<FakeTetherHostFetcher> fake_tether_host_fetcher_;
+  std::unique_ptr<TestingPrefServiceSimple> test_pref_service_;
+
+  std::unique_ptr<FakeDisconnectTetheringOperationFactory>
+      fake_operation_factory_;
+
+  std::string wifi_service_path_;
+  std::string disconnection_result_;
+  bool should_run_disconnect_callbacks_synchronously_;
+  bool should_disconnect_successfully_;
+
+  std::unique_ptr<TetherDisconnectorImpl> tether_disconnector_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TetherDisconnectorImplTest);
+};
+
+TEST_F(TetherDisconnectorImplTest, DisconnectWhenAlreadyDisconnected) {
+  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
+  EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset());
+
+  // Should still be disconnected.
+  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
+            fake_active_host_->GetActiveHostStatus());
+}
+
+TEST_F(TetherDisconnectorImplTest, DisconnectWhenOtherDeviceConnected) {
+  wifi_service_path_ = ConfigureService(
+      CreateConnectedWifiConfigurationJsonString("otherWifiNetworkGuid"));
+  fake_active_host_->SetActiveHostConnected(
+      test_devices_[1].GetDeviceId(),
+      GetTetherNetworkGuid(test_devices_[1].GetDeviceId()),
+      "otherWifiNetworkGuid");
+
+  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
+  EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset());
+
+  // Should still be connected to the other host.
+  EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTED,
+            fake_active_host_->GetActiveHostStatus());
+  EXPECT_EQ(test_devices_[1].GetDeviceId(),
+            fake_active_host_->GetActiveHostDeviceId());
+}
+
+TEST_F(TetherDisconnectorImplTest, DisconnectWhenConnecting_CancelFails) {
+  fake_active_host_->SetActiveHostConnecting(
+      test_devices_[0].GetDeviceId(),
+      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
+  test_tether_connector_->set_should_cancel_successfully(false);
+
+  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
+  EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed,
+            GetResultAndReset());
+  EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()),
+            test_tether_connector_->last_canceled_tether_network_guid());
+
+  // Note: This test does not check the active host's status because it will be
+  // changed by TetherConnector.
+}
+
+TEST_F(TetherDisconnectorImplTest, DisconnectWhenConnecting_CancelSucceeds) {
+  fake_active_host_->SetActiveHostConnecting(
+      test_devices_[0].GetDeviceId(),
+      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
+  test_tether_connector_->set_should_cancel_successfully(true);
+
+  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
+  EXPECT_EQ(kSuccessResult, GetResultAndReset());
+  EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()),
+            test_tether_connector_->last_canceled_tether_network_guid());
+
+  // Note: This test does not check the active host's status because it will be
+  // changed by TetherConnector.
+}
+
+TEST_F(TetherDisconnectorImplTest,
+       DisconnectWhenConnected_NotActuallyConnected) {
+  fake_active_host_->SetActiveHostConnected(
+      test_devices_[0].GetDeviceId(),
+      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()),
+      "nonExistentWifiGuid");
+
+  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
+  EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed,
+            GetResultAndReset());
+
+  // Should be disconnected.
+  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
+            fake_active_host_->GetActiveHostStatus());
+}
+
+TEST_F(TetherDisconnectorImplTest,
+       DisconnectWhenConnected_WifiDisconnectionFails_CannotFetchHost) {
+  fake_active_host_->SetActiveHostConnected(
+      test_devices_[0].GetDeviceId(),
+      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid);
+  SimulateConnectionToWifiNetwork();
+
+  // Remove hosts from |fake_tether_host_fetcher_|; this will cause the fetcher
+  // to return a null RemoteDevice.
+  fake_tether_host_fetcher_->SetTetherHosts(
+      std::vector<cryptauth::RemoteDevice>());
+
+  should_disconnect_successfully_ = false;
+
+  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
+  EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed,
+            GetResultAndReset());
+
+  // The Wi-Fi network should still be connected since disconnection failed.
+  EXPECT_EQ(
+      shill::kStateOnline,
+      GetServiceStringProperty(wifi_service_path_, shill::kStateProperty));
+
+  // Should not have created any operations since the fetch failed.
+  EXPECT_TRUE(fake_operation_factory_->created_operations().empty());
+
+  // Should be disconnected.
+  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
+            fake_active_host_->GetActiveHostStatus());
+}
+
+TEST_F(TetherDisconnectorImplTest,
+       DisconnectWhenConnected_WifiDisconnectionSucceeds_CannotFetchHost) {
+  fake_active_host_->SetActiveHostConnected(
+      test_devices_[0].GetDeviceId(),
+      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid);
+  SimulateConnectionToWifiNetwork();
+
+  // Remove hosts from |fake_tether_host_fetcher_|; this will cause the fetcher
+  // to return a null RemoteDevice.
+  fake_tether_host_fetcher_->SetTetherHosts(
+      std::vector<cryptauth::RemoteDevice>());
+
+  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
+  EXPECT_EQ(kSuccessResult, GetResultAndReset());
+
+  // The Wi-Fi network should be disconnected.
+  EXPECT_EQ(shill::kStateIdle, GetServiceStringProperty(wifi_service_path_,
+                                                        shill::kStateProperty));
+
+  // Should not have created any operations since the fetch failed.
+  EXPECT_TRUE(fake_operation_factory_->created_operations().empty());
+
+  // Should be disconnected.
+  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
+            fake_active_host_->GetActiveHostStatus());
+}
+
+TEST_F(TetherDisconnectorImplTest,
+       DisconnectWhenConnected_WifiDisconnectionFails_OperationFails) {
+  fake_active_host_->SetActiveHostConnected(
+      test_devices_[0].GetDeviceId(),
+      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid);
+  SimulateConnectionToWifiNetwork();
+
+  should_disconnect_successfully_ = false;
+
+  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
+  EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed,
+            GetResultAndReset());
+
+  // The Wi-Fi network should still be connected since disconnection failed.
+  EXPECT_EQ(
+      shill::kStateOnline,
+      GetServiceStringProperty(wifi_service_path_, shill::kStateProperty));
+
+  // Fail the operation.
+  ASSERT_EQ(1u, fake_operation_factory_->created_operations().size());
+  EXPECT_EQ(
+      test_devices_[0],
+      fake_operation_factory_->created_operations()[0]->GetRemoteDevice());
+  fake_operation_factory_->created_operations()[0]->NotifyFinished(
+      false /* success */);
+
+  // Should be disconnected.
+  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
+            fake_active_host_->GetActiveHostStatus());
+}
+
+TEST_F(TetherDisconnectorImplTest,
+       DisconnectWhenConnected_WifiDisconnectionSucceeds_OperationFails) {
+  fake_active_host_->SetActiveHostConnected(
+      test_devices_[0].GetDeviceId(),
+      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid);
+  SimulateConnectionToWifiNetwork();
+
+  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
+  EXPECT_EQ(kSuccessResult, GetResultAndReset());
+
+  // The Wi-Fi network should be disconnected.
+  EXPECT_EQ(shill::kStateIdle, GetServiceStringProperty(wifi_service_path_,
+                                                        shill::kStateProperty));
+
+  ASSERT_EQ(1u, fake_operation_factory_->created_operations().size());
+  EXPECT_EQ(
+      test_devices_[0],
+      fake_operation_factory_->created_operations()[0]->GetRemoteDevice());
+  fake_operation_factory_->created_operations()[0]->NotifyFinished(
+      false /* success */);
+
+  // Should be disconnected.
+  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
+            fake_active_host_->GetActiveHostStatus());
+}
+
+TEST_F(TetherDisconnectorImplTest,
+       DisconnectWhenConnected_WifiDisconnectionFails_OperationSucceeds) {
+  fake_active_host_->SetActiveHostConnected(
+      test_devices_[0].GetDeviceId(),
+      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid);
+  SimulateConnectionToWifiNetwork();
+
+  should_disconnect_successfully_ = false;
+
+  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
+  EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed,
+            GetResultAndReset());
+
+  // The Wi-Fi network should still be connected since disconnection failed.
+  EXPECT_EQ(
+      shill::kStateOnline,
+      GetServiceStringProperty(wifi_service_path_, shill::kStateProperty));
+
+  // Fail the operation.
+  ASSERT_EQ(1u, fake_operation_factory_->created_operations().size());
+  EXPECT_EQ(
+      test_devices_[0],
+      fake_operation_factory_->created_operations()[0]->GetRemoteDevice());
+  fake_operation_factory_->created_operations()[0]->NotifyFinished(
+      true /* success */);
+
+  // Should be disconnected.
+  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
+            fake_active_host_->GetActiveHostStatus());
+}
+
+TEST_F(TetherDisconnectorImplTest,
+       DisconnectWhenConnected_WifiDisconnectionSucceeds_OperationSucceeds) {
+  fake_active_host_->SetActiveHostConnected(
+      test_devices_[0].GetDeviceId(),
+      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid);
+  SimulateConnectionToWifiNetwork();
+
+  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
+  EXPECT_EQ(kSuccessResult, GetResultAndReset());
+
+  // The Wi-Fi network should be disconnected.
+  EXPECT_EQ(shill::kStateIdle, GetServiceStringProperty(wifi_service_path_,
+                                                        shill::kStateProperty));
+
+  ASSERT_EQ(1u, fake_operation_factory_->created_operations().size());
+  EXPECT_EQ(
+      test_devices_[0],
+      fake_operation_factory_->created_operations()[0]->GetRemoteDevice());
+  fake_operation_factory_->created_operations()[0]->NotifyFinished(
+      true /* success */);
+
+  // Should be disconnected.
+  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
+            fake_active_host_->GetActiveHostStatus());
+}
+
+TEST_F(TetherDisconnectorImplTest,
+       DisconnectWhenConnected_DestroyBeforeOperationComplete) {
+  fake_active_host_->SetActiveHostConnected(
+      test_devices_[0].GetDeviceId(),
+      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid);
+  SimulateConnectionToWifiNetwork();
+
+  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
+  EXPECT_EQ(kSuccessResult, GetResultAndReset());
+
+  // Stop the test here, before the operation responds in any way. This test
+  // ensures that TetherDisconnectorImpl properly removes existing listeners
+  // if it is destroyed while there are still active operations.
+}
+
+TEST_F(TetherDisconnectorImplTest, DisconnectsWhenDestructorCalled) {
+  // For this test, do not synchronously reply with results. This echos what
+  // actually happens when a TetherDisconnectorImpl is deleted.
+  should_run_disconnect_callbacks_synchronously_ = false;
+  fake_tether_host_fetcher_->set_synchronously_reply_with_results(false);
+
+  fake_active_host_->SetActiveHostConnected(
+      test_devices_[0].GetDeviceId(),
+      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid);
+  SimulateConnectionToWifiNetwork();
+
+  // Destroy the object, which should result in a disconnection.
+  tether_disconnector_.reset();
+
+  // Because the object is destroyed before the disconnection callback occurs,
+  // no result should have been able to be set.
+  EXPECT_EQ(std::string(), GetResultAndReset());
+
+  // The Wi-Fi network should be disconnected.
+  EXPECT_EQ(shill::kStateIdle, GetServiceStringProperty(wifi_service_path_,
+                                                        shill::kStateProperty));
+
+  // Because the fetcher does not synchronously reply with results,
+  // |tether_disconnector_| should be deleted before any operations can be
+  // created.
+  EXPECT_TRUE(fake_operation_factory_->created_operations().empty());
+
+  // Should be disconnected.
+  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
+            fake_active_host_->GetActiveHostStatus());
+
+  // Because the disconnection did not fully complete, the configuration should
+  // not yet have been cleaned up, and prefs should still contain the
+  // disconnecting Wi-Fi GUID.
+  EXPECT_TRUE(
+      fake_network_configuration_remover_->last_removed_wifi_network_guid()
+          .empty());
+  EXPECT_EQ(kWifiNetworkGuid, GetDisconnectingWifiGuidFromPrefs());
+
+  // Now, create a new TetherDisconnectorImpl instance. This should clean up
+  // the previous disconnection attempt.
+  tether_disconnector_ = base::MakeUnique<TetherDisconnectorImpl>(
+      test_network_connection_handler_.get(), network_state_handler(),
+      fake_active_host_.get(), fake_ble_connection_manager_.get(),
+      fake_network_configuration_remover_.get(), test_tether_connector_.get(),
+      device_id_tether_network_guid_map_.get(), fake_tether_host_fetcher_.get(),
+      test_pref_service_.get());
+  EXPECT_EQ(
+      kWifiNetworkGuid,
+      fake_network_configuration_remover_->last_removed_wifi_network_guid());
+  EXPECT_TRUE(GetDisconnectingWifiGuidFromPrefs().empty());
+}
+
+}  // namespace tether
+
+}  // namespace chromeos
diff --git a/chromeos/components/tether/tether_disconnector_unittest.cc b/chromeos/components/tether/tether_disconnector_unittest.cc
deleted file mode 100644
index b421426..0000000
--- a/chromeos/components/tether/tether_disconnector_unittest.cc
+++ /dev/null
@@ -1,592 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromeos/components/tether/tether_disconnector.h"
-
-#include "base/memory/ptr_util.h"
-#include "base/message_loop/message_loop.h"
-#include "chromeos/components/tether/connect_tethering_operation.h"
-#include "chromeos/components/tether/device_id_tether_network_guid_map.h"
-#include "chromeos/components/tether/fake_active_host.h"
-#include "chromeos/components/tether/fake_ble_connection_manager.h"
-#include "chromeos/components/tether/fake_network_configuration_remover.h"
-#include "chromeos/components/tether/fake_tether_host_fetcher.h"
-#include "chromeos/components/tether/fake_wifi_hotspot_connector.h"
-#include "chromeos/components/tether/mock_tether_host_response_recorder.h"
-#include "chromeos/components/tether/tether_connector.h"
-#include "chromeos/dbus/dbus_thread_manager.h"
-#include "chromeos/network/network_connection_handler.h"
-#include "chromeos/network/network_state.h"
-#include "chromeos/network/network_state_handler.h"
-#include "chromeos/network/network_state_test.h"
-#include "components/cryptauth/remote_device.h"
-#include "components/cryptauth/remote_device_test_util.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/cros_system_api/dbus/shill/dbus-constants.h"
-
-namespace chromeos {
-
-namespace tether {
-
-namespace {
-
-const char kSuccessResult[] = "success";
-
-const char kWifiNetworkGuid[] = "wifiNetworkGuid";
-
-std::string CreateConnectedWifiConfigurationJsonString() {
-  std::stringstream ss;
-  ss << "{"
-     << "  \"GUID\": \"" << kWifiNetworkGuid << "\","
-     << "  \"Type\": \"" << shill::kTypeWifi << "\","
-     << "  \"State\": \"" << shill::kStateOnline << "\""
-     << "}";
-  return ss.str();
-}
-
-class TestNetworkConnectionHandler : public NetworkConnectionHandler {
- public:
-  explicit TestNetworkConnectionHandler(base::Closure disconnect_callback)
-      : disconnect_callback_(disconnect_callback) {}
-  ~TestNetworkConnectionHandler() override {}
-
-  std::string last_disconnect_service_path() {
-    return last_disconnect_service_path_;
-  }
-
-  base::Closure last_disconnect_success_callback() {
-    return last_disconnect_success_callback_;
-  }
-
-  network_handler::ErrorCallback last_disconnect_error_callback() {
-    return last_disconnect_error_callback_;
-  }
-
-  // NetworkConnectionHandler:
-  void DisconnectNetwork(
-      const std::string& service_path,
-      const base::Closure& success_callback,
-      const network_handler::ErrorCallback& error_callback) override {
-    last_disconnect_service_path_ = service_path;
-    last_disconnect_success_callback_ = success_callback;
-    last_disconnect_error_callback_ = error_callback;
-
-    disconnect_callback_.Run();
-  }
-  void ConnectToNetwork(const std::string& service_path,
-                        const base::Closure& success_callback,
-                        const network_handler::ErrorCallback& error_callback,
-                        bool check_error_state) override {}
-  bool HasConnectingNetwork(const std::string& service_path) override {
-    return false;
-  }
-  bool HasPendingConnectRequest() override { return false; }
-  void Init(NetworkStateHandler* network_state_handler,
-            NetworkConfigurationHandler* network_configuration_handler,
-            ManagedNetworkConfigurationHandler*
-                managed_network_configuration_handler) override {}
-
- private:
-  base::Closure disconnect_callback_;
-
-  std::string last_disconnect_service_path_;
-  base::Closure last_disconnect_success_callback_;
-  network_handler::ErrorCallback last_disconnect_error_callback_;
-};
-
-class TestTetherConnector : public TetherConnector {
- public:
-  TestTetherConnector()
-      : TetherConnector(nullptr /* network_state_handler */,
-                        nullptr /* wifi_hotspot_connector */,
-                        nullptr /* active_host */,
-                        nullptr /* tether_host_fetcher */,
-                        nullptr /* connection_manager */,
-                        nullptr /* tether_host_response_recorder */,
-                        nullptr /* device_id_tether_network_guid_map */,
-                        nullptr /* host_scan_cache */,
-                        nullptr /* notification_presenter */),
-        should_cancel_successfully_(true) {}
-  ~TestTetherConnector() override {}
-
-  void set_should_cancel_successfully(bool should_cancel_successfully) {
-    should_cancel_successfully_ = should_cancel_successfully;
-  }
-
-  std::string last_canceled_tether_network_guid() {
-    return last_canceled_tether_network_guid_;
-  }
-
-  // TetherConnector:
-  bool CancelConnectionAttempt(
-      const std::string& tether_network_guid) override {
-    last_canceled_tether_network_guid_ = tether_network_guid;
-    return should_cancel_successfully_;
-  }
-
- private:
-  bool should_cancel_successfully_;
-  std::string last_canceled_tether_network_guid_;
-};
-
-class FakeDisconnectTetheringOperation : public DisconnectTetheringOperation {
- public:
-  FakeDisconnectTetheringOperation(
-      const cryptauth::RemoteDevice& device_to_connect,
-      BleConnectionManager* connection_manager)
-      : DisconnectTetheringOperation(device_to_connect, connection_manager) {}
-
-  ~FakeDisconnectTetheringOperation() override {}
-
-  void NotifyFinished(bool success) {
-    NotifyObserversOperationFinished(success);
-  }
-
-  cryptauth::RemoteDevice GetRemoteDevice() {
-    EXPECT_EQ(1u, remote_devices().size());
-    return remote_devices()[0];
-  }
-};
-
-class FakeDisconnectTetheringOperationFactory
-    : public DisconnectTetheringOperation::Factory {
- public:
-  FakeDisconnectTetheringOperationFactory() {}
-  virtual ~FakeDisconnectTetheringOperationFactory() {}
-
-  std::vector<FakeDisconnectTetheringOperation*>& created_operations() {
-    return created_operations_;
-  }
-
- protected:
-  // DisconnectTetheringOperation::Factory:
-  std::unique_ptr<DisconnectTetheringOperation> BuildInstance(
-      const cryptauth::RemoteDevice& device_to_connect,
-      BleConnectionManager* connection_manager) override {
-    FakeDisconnectTetheringOperation* operation =
-        new FakeDisconnectTetheringOperation(device_to_connect,
-                                             connection_manager);
-    created_operations_.push_back(operation);
-    return base::WrapUnique(operation);
-  }
-
- private:
-  std::vector<FakeDisconnectTetheringOperation*> created_operations_;
-};
-
-}  // namespace
-
-class TetherDisconnectorTest : public NetworkStateTest {
- public:
-  TetherDisconnectorTest()
-      : test_devices_(cryptauth::GenerateTestRemoteDevices(2u)) {}
-  ~TetherDisconnectorTest() override {}
-
-  void SetUp() override {
-    DBusThreadManager::Initialize();
-    NetworkStateTest::SetUp();
-
-    should_disconnect_successfully_ = true;
-
-    test_network_connection_handler_ =
-        base::WrapUnique(new TestNetworkConnectionHandler(base::Bind(
-            &TetherDisconnectorTest::OnNetworkConnectionManagerDisconnect,
-            base::Unretained(this))));
-    fake_active_host_ = base::MakeUnique<FakeActiveHost>();
-    fake_ble_connection_manager_ = base::MakeUnique<FakeBleConnectionManager>();
-    fake_network_configuration_remover_ =
-        base::MakeUnique<FakeNetworkConfigurationRemover>();
-    test_tether_connector_ = base::WrapUnique(new TestTetherConnector());
-    device_id_tether_network_guid_map_ =
-        base::MakeUnique<DeviceIdTetherNetworkGuidMap>();
-    fake_tether_host_fetcher_ = base::MakeUnique<FakeTetherHostFetcher>(
-        test_devices_, true /* synchronously_reply_with_results */);
-
-    fake_operation_factory_ =
-        base::WrapUnique(new FakeDisconnectTetheringOperationFactory());
-    DisconnectTetheringOperation::Factory::SetInstanceForTesting(
-        fake_operation_factory_.get());
-
-    SetUpTetherNetworks();
-
-    tether_disconnector_ = base::MakeUnique<TetherDisconnector>(
-        test_network_connection_handler_.get(), network_state_handler(),
-        fake_active_host_.get(), fake_ble_connection_manager_.get(),
-        fake_network_configuration_remover_.get(), test_tether_connector_.get(),
-        device_id_tether_network_guid_map_.get(),
-        fake_tether_host_fetcher_.get());
-  }
-
-  void TearDown() override {
-    ShutdownNetworkState();
-    NetworkStateTest::TearDown();
-    DBusThreadManager::Shutdown();
-  }
-
-  std::string GetTetherNetworkGuid(const std::string& device_id) {
-    return device_id_tether_network_guid_map_->GetTetherNetworkGuidForDeviceId(
-        device_id);
-  }
-
-  void SetUpTetherNetworks() {
-    network_state_handler()->SetTetherTechnologyState(
-        NetworkStateHandler::TECHNOLOGY_ENABLED);
-
-    // Add a tether network corresponding to both of the test devices. These
-    // networks are expected to be added already before
-    // TetherDisconnector::DisconnectFromNetwork() is called.
-    network_state_handler()->AddTetherNetworkState(
-        GetTetherNetworkGuid(test_devices_[0].GetDeviceId()),
-        "TetherNetworkName1", "TetherNetworkCarrier1",
-        85 /* battery_percentage */, 75 /* signal_strength */,
-        true /* has_connected_to_host */);
-    network_state_handler()->AddTetherNetworkState(
-        GetTetherNetworkGuid(test_devices_[1].GetDeviceId()),
-        "TetherNetworkName2", "TetherNetworkCarrier2",
-        90 /* battery_percentage */, 50 /* signal_strength */,
-        true /* has_connected_to_host */);
-  }
-
-  void SimulateConnectionToWifiNetwork() {
-    wifi_service_path_ =
-        ConfigureService(CreateConnectedWifiConfigurationJsonString());
-    EXPECT_FALSE(wifi_service_path_.empty());
-  }
-
-  void SuccessCallback() { disconnection_result_ = kSuccessResult; }
-
-  void ErrorCallback(const std::string& error_name) {
-    disconnection_result_ = error_name;
-  }
-
-  void CallDisconnect(const std::string& tether_network_guid) {
-    tether_disconnector_->DisconnectFromNetwork(
-        tether_network_guid,
-        base::Bind(&TetherDisconnectorTest::SuccessCallback,
-                   base::Unretained(this)),
-        base::Bind(&TetherDisconnectorTest::ErrorCallback,
-                   base::Unretained(this)));
-  }
-
-  // This function is called by
-  // TestNetworkConnectionHandler::DisconnectFromNetwork().
-  void OnNetworkConnectionManagerDisconnect() {
-    EXPECT_EQ(wifi_service_path_,
-              test_network_connection_handler_->last_disconnect_service_path());
-
-    if (should_disconnect_successfully_) {
-      SetServiceProperty(wifi_service_path_, shill::kStateProperty,
-                         base::Value(shill::kStateIdle));
-      EXPECT_FALSE(
-          test_network_connection_handler_->last_disconnect_success_callback()
-              .is_null());
-      test_network_connection_handler_->last_disconnect_success_callback()
-          .Run();
-    } else {
-      EXPECT_FALSE(
-          test_network_connection_handler_->last_disconnect_error_callback()
-              .is_null());
-      network_handler::RunErrorCallback(
-          test_network_connection_handler_->last_disconnect_error_callback(),
-          wifi_service_path_, NetworkConnectionHandler::kErrorDisconnectFailed,
-          "" /* error_detail */);
-    }
-  }
-
-  std::string GetResultAndReset() {
-    std::string result;
-    result.swap(disconnection_result_);
-    return result;
-  }
-
-  const std::vector<cryptauth::RemoteDevice> test_devices_;
-  const base::MessageLoop message_loop_;
-
-  std::unique_ptr<TestNetworkConnectionHandler>
-      test_network_connection_handler_;
-  std::unique_ptr<FakeActiveHost> fake_active_host_;
-  std::unique_ptr<FakeBleConnectionManager> fake_ble_connection_manager_;
-  std::unique_ptr<FakeNetworkConfigurationRemover>
-      fake_network_configuration_remover_;
-  std::unique_ptr<TestTetherConnector> test_tether_connector_;
-  // TODO(hansberry): Use a fake for this when a real mapping scheme is created.
-  std::unique_ptr<DeviceIdTetherNetworkGuidMap>
-      device_id_tether_network_guid_map_;
-  std::unique_ptr<FakeTetherHostFetcher> fake_tether_host_fetcher_;
-
-  std::unique_ptr<FakeDisconnectTetheringOperationFactory>
-      fake_operation_factory_;
-
-  std::string wifi_service_path_;
-  std::string disconnection_result_;
-  bool should_disconnect_successfully_;
-
-  std::unique_ptr<TetherDisconnector> tether_disconnector_;
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(TetherDisconnectorTest);
-};
-
-TEST_F(TetherDisconnectorTest, DisconnectWhenAlreadyDisconnected) {
-  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
-  EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset());
-
-  // Should still be disconnected.
-  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
-            fake_active_host_->GetActiveHostStatus());
-}
-
-TEST_F(TetherDisconnectorTest, DisconnectWhenOtherDeviceConnected) {
-  fake_active_host_->SetActiveHostConnected(
-      test_devices_[1].GetDeviceId(),
-      GetTetherNetworkGuid(test_devices_[1].GetDeviceId()),
-      "otherWifiNetworkGuid");
-
-  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
-  EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset());
-
-  // Should still be connected to the other host.
-  EXPECT_EQ(ActiveHost::ActiveHostStatus::CONNECTED,
-            fake_active_host_->GetActiveHostStatus());
-  EXPECT_EQ(test_devices_[1].GetDeviceId(),
-            fake_active_host_->GetActiveHostDeviceId());
-}
-
-TEST_F(TetherDisconnectorTest, DisconnectWhenConnecting_CancelFails) {
-  fake_active_host_->SetActiveHostConnecting(
-      test_devices_[0].GetDeviceId(),
-      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
-  test_tether_connector_->set_should_cancel_successfully(false);
-
-  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
-  EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed,
-            GetResultAndReset());
-  EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()),
-            test_tether_connector_->last_canceled_tether_network_guid());
-
-  // Note: This test does not check the active host's status because it will be
-  // changed by TetherConnector.
-}
-
-TEST_F(TetherDisconnectorTest, DisconnectWhenConnecting_CancelSucceeds) {
-  fake_active_host_->SetActiveHostConnecting(
-      test_devices_[0].GetDeviceId(),
-      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
-  test_tether_connector_->set_should_cancel_successfully(true);
-
-  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
-  EXPECT_EQ(kSuccessResult, GetResultAndReset());
-  EXPECT_EQ(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()),
-            test_tether_connector_->last_canceled_tether_network_guid());
-
-  // Note: This test does not check the active host's status because it will be
-  // changed by TetherConnector.
-}
-
-TEST_F(TetherDisconnectorTest, DisconnectWhenConnected_NotActuallyConnected) {
-  fake_active_host_->SetActiveHostConnected(
-      test_devices_[0].GetDeviceId(),
-      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()),
-      "nonExistentWifiGuid");
-
-  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
-  EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed,
-            GetResultAndReset());
-
-  // Should be disconnected.
-  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
-            fake_active_host_->GetActiveHostStatus());
-}
-
-TEST_F(TetherDisconnectorTest,
-       DisconnectWhenConnected_WifiConnectionFails_CannotFetchHost) {
-  fake_active_host_->SetActiveHostConnected(
-      test_devices_[0].GetDeviceId(),
-      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid);
-  SimulateConnectionToWifiNetwork();
-
-  // Remove hosts from |fake_tether_host_fetcher_|; this will cause the fetcher
-  // to return a null RemoteDevice.
-  fake_tether_host_fetcher_->SetTetherHosts(
-      std::vector<cryptauth::RemoteDevice>());
-
-  should_disconnect_successfully_ = false;
-
-  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
-  EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed,
-            GetResultAndReset());
-
-  // The Wi-Fi network should still be connected since disconnection failed.
-  EXPECT_EQ(
-      shill::kStateOnline,
-      GetServiceStringProperty(wifi_service_path_, shill::kStateProperty));
-
-  // Should not have created any operations since the fetch failed.
-  EXPECT_TRUE(fake_operation_factory_->created_operations().empty());
-
-  // Should be disconnected.
-  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
-            fake_active_host_->GetActiveHostStatus());
-}
-
-TEST_F(TetherDisconnectorTest,
-       DisconnectWhenConnected_WifiConnectionSucceeds_CannotFetchHost) {
-  fake_active_host_->SetActiveHostConnected(
-      test_devices_[0].GetDeviceId(),
-      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid);
-  SimulateConnectionToWifiNetwork();
-
-  // Remove hosts from |fake_tether_host_fetcher_|; this will cause the fetcher
-  // to return a null RemoteDevice.
-  fake_tether_host_fetcher_->SetTetherHosts(
-      std::vector<cryptauth::RemoteDevice>());
-
-  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
-  EXPECT_EQ(kSuccessResult, GetResultAndReset());
-
-  // The Wi-Fi network should be disconnected since disconnection failed.
-  EXPECT_EQ(shill::kStateIdle, GetServiceStringProperty(wifi_service_path_,
-                                                        shill::kStateProperty));
-
-  // Should not have created any operations since the fetch failed.
-  EXPECT_TRUE(fake_operation_factory_->created_operations().empty());
-
-  // Should be disconnected.
-  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
-            fake_active_host_->GetActiveHostStatus());
-}
-
-TEST_F(TetherDisconnectorTest,
-       DisconnectWhenConnected_WifiConnectionFails_OperationFails) {
-  fake_active_host_->SetActiveHostConnected(
-      test_devices_[0].GetDeviceId(),
-      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid);
-  SimulateConnectionToWifiNetwork();
-
-  should_disconnect_successfully_ = false;
-
-  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
-  EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed,
-            GetResultAndReset());
-
-  // The Wi-Fi network should still be connected since disconnection failed.
-  EXPECT_EQ(
-      shill::kStateOnline,
-      GetServiceStringProperty(wifi_service_path_, shill::kStateProperty));
-
-  // Fail the operation.
-  ASSERT_EQ(1u, fake_operation_factory_->created_operations().size());
-  EXPECT_EQ(
-      test_devices_[0],
-      fake_operation_factory_->created_operations()[0]->GetRemoteDevice());
-  fake_operation_factory_->created_operations()[0]->NotifyFinished(
-      false /* success */);
-
-  // Should be disconnected.
-  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
-            fake_active_host_->GetActiveHostStatus());
-}
-
-TEST_F(TetherDisconnectorTest,
-       DisconnectWhenConnected_WifiConnectionSucceeds_OperationFails) {
-  fake_active_host_->SetActiveHostConnected(
-      test_devices_[0].GetDeviceId(),
-      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid);
-  SimulateConnectionToWifiNetwork();
-
-  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
-  EXPECT_EQ(kSuccessResult, GetResultAndReset());
-
-  // The Wi-Fi network should be disconnected since disconnection failed.
-  EXPECT_EQ(shill::kStateIdle, GetServiceStringProperty(wifi_service_path_,
-                                                        shill::kStateProperty));
-
-  ASSERT_EQ(1u, fake_operation_factory_->created_operations().size());
-  EXPECT_EQ(
-      test_devices_[0],
-      fake_operation_factory_->created_operations()[0]->GetRemoteDevice());
-  fake_operation_factory_->created_operations()[0]->NotifyFinished(
-      false /* success */);
-
-  // Should be disconnected.
-  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
-            fake_active_host_->GetActiveHostStatus());
-}
-
-TEST_F(TetherDisconnectorTest,
-       DisconnectWhenConnected_WifiConnectionFails_OperationSucceeds) {
-  fake_active_host_->SetActiveHostConnected(
-      test_devices_[0].GetDeviceId(),
-      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid);
-  SimulateConnectionToWifiNetwork();
-
-  should_disconnect_successfully_ = false;
-
-  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
-  EXPECT_EQ(NetworkConnectionHandler::kErrorDisconnectFailed,
-            GetResultAndReset());
-
-  // The Wi-Fi network should still be connected since disconnection failed.
-  EXPECT_EQ(
-      shill::kStateOnline,
-      GetServiceStringProperty(wifi_service_path_, shill::kStateProperty));
-
-  // Fail the operation.
-  ASSERT_EQ(1u, fake_operation_factory_->created_operations().size());
-  EXPECT_EQ(
-      test_devices_[0],
-      fake_operation_factory_->created_operations()[0]->GetRemoteDevice());
-  fake_operation_factory_->created_operations()[0]->NotifyFinished(
-      true /* success */);
-
-  // Should be disconnected.
-  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
-            fake_active_host_->GetActiveHostStatus());
-}
-
-TEST_F(TetherDisconnectorTest,
-       DisconnectWhenConnected_WifiConnectionSucceeds_OperationSucceeds) {
-  fake_active_host_->SetActiveHostConnected(
-      test_devices_[0].GetDeviceId(),
-      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid);
-  SimulateConnectionToWifiNetwork();
-
-  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
-  EXPECT_EQ(kSuccessResult, GetResultAndReset());
-
-  // The Wi-Fi network should be disconnected since disconnection failed.
-  EXPECT_EQ(shill::kStateIdle, GetServiceStringProperty(wifi_service_path_,
-                                                        shill::kStateProperty));
-
-  ASSERT_EQ(1u, fake_operation_factory_->created_operations().size());
-  EXPECT_EQ(
-      test_devices_[0],
-      fake_operation_factory_->created_operations()[0]->GetRemoteDevice());
-  fake_operation_factory_->created_operations()[0]->NotifyFinished(
-      true /* success */);
-
-  // Should be disconnected.
-  EXPECT_EQ(ActiveHost::ActiveHostStatus::DISCONNECTED,
-            fake_active_host_->GetActiveHostStatus());
-}
-
-TEST_F(TetherDisconnectorTest,
-       DisconnectWhenConnected_DestroyBeforeOperationComplete) {
-  fake_active_host_->SetActiveHostConnected(
-      test_devices_[0].GetDeviceId(),
-      GetTetherNetworkGuid(test_devices_[0].GetDeviceId()), kWifiNetworkGuid);
-  SimulateConnectionToWifiNetwork();
-
-  CallDisconnect(GetTetherNetworkGuid(test_devices_[0].GetDeviceId()));
-  EXPECT_EQ(kSuccessResult, GetResultAndReset());
-
-  // Stop the test here, before the operation responds in any way. This test
-  // ensures that TetherDisconnector properly removes existing listeners if it
-  // is destroyed while there are still active operations.
-}
-
-}  // namespace tether
-
-}  // namespace chromeos
diff --git a/chromeos/components/tether/tether_host_response_recorder.h b/chromeos/components/tether/tether_host_response_recorder.h
index fed179e8c..ad2ed04 100644
--- a/chromeos/components/tether/tether_host_response_recorder.h
+++ b/chromeos/components/tether/tether_host_response_recorder.h
@@ -69,7 +69,7 @@
   virtual std::vector<std::string> GetPreviouslyConnectedHostIds() const;
 
  private:
-  friend class HostScanCacheTest;
+  friend class MasterHostScanCacheTest;
 
   void NotifyObserversPreviouslyConnectedHostIdsChanged();
 
diff --git a/components/autofill/android/form_data_android.cc b/components/autofill/android/form_data_android.cc
index 8a8af68..6cfb4f9 100644
--- a/components/autofill/android/form_data_android.cc
+++ b/components/autofill/android/form_data_android.cc
@@ -41,7 +41,7 @@
     ScopedJavaLocalRef<jstring> jname =
         ConvertUTF16ToJavaString(env, form_.name);
     ScopedJavaLocalRef<jstring> jhost =
-        ConvertUTF8ToJavaString(env, form_.origin.host());
+        ConvertUTF8ToJavaString(env, form_.origin.GetOrigin().spec());
     obj = Java_FormData_createFormData(env, reinterpret_cast<intptr_t>(this),
                                        jname, jhost, form_.fields.size());
     java_ref_ = JavaObjectWeakGlobalRef(env, obj);
diff --git a/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc b/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
index d28102a..0857cc6 100644
--- a/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
+++ b/components/autofill/core/browser/autofill_save_card_infobar_delegate_mobile.cc
@@ -44,7 +44,8 @@
       card_label_(base::string16(kMidlineEllipsis) + card.LastFourDigits()),
       card_sub_label_(card.AbbreviatedExpirationDateForDisplay()) {
   if (legal_message) {
-    if (!LegalMessageLine::Parse(*legal_message, &legal_messages_)) {
+    if (!LegalMessageLine::Parse(*legal_message, &legal_messages_,
+                                 /*escape_apostrophes=*/true)) {
       AutofillMetrics::LogCreditCardInfoBarMetric(
           AutofillMetrics::INFOBAR_NOT_SHOWN_INVALID_LEGAL_MESSAGE, upload_,
           pref_service_->GetInteger(
diff --git a/components/autofill/core/browser/legal_message_line.cc b/components/autofill/core/browser/legal_message_line.cc
index 71bf0aa..dc28aebb 100644
--- a/components/autofill/core/browser/legal_message_line.cc
+++ b/components/autofill/core/browser/legal_message_line.cc
@@ -79,7 +79,8 @@
 
 // static
 bool LegalMessageLine::Parse(const base::DictionaryValue& legal_message,
-                             LegalMessageLines* out) {
+                             LegalMessageLines* out,
+                             bool escape_apostrophes) {
   const base::ListValue* lines_list = nullptr;
   if (legal_message.GetList("line", &lines_list)) {
     LegalMessageLines lines;
@@ -88,7 +89,7 @@
       lines.emplace_back(LegalMessageLine());
       const base::DictionaryValue* single_line;
       if (!lines_list->GetDictionary(i, &single_line) ||
-          !lines.back().ParseLine(*single_line))
+          !lines.back().ParseLine(*single_line, escape_apostrophes))
         return false;
     }
 
@@ -98,7 +99,8 @@
   return true;
 }
 
-bool LegalMessageLine::ParseLine(const base::DictionaryValue& line) {
+bool LegalMessageLine::ParseLine(const base::DictionaryValue& line,
+                                 bool escape_apostrophes) {
   DCHECK(text_.empty());
   DCHECK(links_.empty());
 
@@ -133,6 +135,17 @@
   if (!line.GetString("template", &template_icu))
     return false;
 
+  if (escape_apostrophes) {
+    // The ICU standard counts "'{" as beginning an escaped string literal, even
+    // if there's no closing apostrophe.  This fails legal message templates
+    // where an apostrophe precedes the template parameter, like "l'{1}" in
+    // Italian.  Therefore, when |escape_apostrophes| is true, escape all
+    // apostrophes in the string by doubling them up.
+    // http://www.icu-project.org/apiref/icu4c/messagepattern_8h.html#af6e0757e0eb81c980b01ee5d68a9978b
+    base::ReplaceChars(template_icu, base::ASCIIToUTF16("'"),
+                       base::ASCIIToUTF16("''"), &template_icu);
+  }
+
   // Replace the placeholders in |template_icu| with strings from
   // |display_texts|, and store the start position of each replacement in
   // |offsets|.
diff --git a/components/autofill/core/browser/legal_message_line.h b/components/autofill/core/browser/legal_message_line.h
index 50955f9..141ea92d 100644
--- a/components/autofill/core/browser/legal_message_line.h
+++ b/components/autofill/core/browser/legal_message_line.h
@@ -64,8 +64,13 @@
   // 3. "${" anywhere in the template string is invalid.
   // 4. "\n" embedded anywhere in the template string, or an empty template
   //    string, can be used to separate paragraphs.
+  // 5. Because a single apostrophe before a curly brace starts quoted literal
+  //    text in MessageFormat, "'{0}" gets treated as a literal.  To avoid
+  //    situations like these, setting |escape_apostrophes| to true will escape
+  //    all ASCII apostrophes by doubling them up.
   static bool Parse(const base::DictionaryValue& legal_message,
-                    LegalMessageLines* out);
+                    LegalMessageLines* out,
+                    bool escape_apostrophes = false);
 
   const base::string16& text() const { return text_; }
   const std::vector<Link>& links() const { return links_; }
@@ -73,7 +78,7 @@
  private:
   friend class TestLegalMessageLine;
 
-  bool ParseLine(const base::DictionaryValue& line);
+  bool ParseLine(const base::DictionaryValue& line, bool escape_apostrophes);
 
   base::string16 text_;
   std::vector<Link> links_;
diff --git a/components/autofill/core/browser/legal_message_line_unittest.cc b/components/autofill/core/browser/legal_message_line_unittest.cc
index a65bc3dc..e3147f1e 100644
--- a/components/autofill/core/browser/legal_message_line_unittest.cc
+++ b/components/autofill/core/browser/legal_message_line_unittest.cc
@@ -47,6 +47,7 @@
 struct TestCase {
   std::string message_json;
   LegalMessageLines expected_lines;
+  bool escape_apostrophes;
 };
 
 // Prints out a legal message |line| to |os|.
@@ -109,7 +110,8 @@
   EXPECT_TRUE(value->GetAsDictionary(&dictionary));
   ASSERT_TRUE(dictionary);
   LegalMessageLines actual_lines;
-  LegalMessageLine::Parse(*dictionary, &actual_lines);
+  LegalMessageLine::Parse(*dictionary, &actual_lines,
+                          GetParam().escape_apostrophes);
 
   EXPECT_EQ(GetParam().expected_lines, actual_lines);
 };
@@ -272,41 +274,58 @@
                                    Link(24, 30, "http://www.example.com/1"),
                                    Link(17, 19, "http://www.example.com/2"),
                                    Link(36, 39, "http://www.example.com/3")})}},
-        TestCase{"{"
-                 "  \"line\" : [ {"
-                 "    \"template\": \"a{0} b{1} c{2} d{3} e{4} f{5} g{6}\","
-                 "    \"template_parameter\": [ {"
-                 "      \"display_text\": \"A\","
-                 "      \"url\": \"http://www.example.com/0\""
-                 "    }, {"
-                 "      \"display_text\": \"B\","
-                 "      \"url\": \"http://www.example.com/1\""
-                 "    }, {"
-                 "      \"display_text\": \"C\","
-                 "      \"url\": \"http://www.example.com/2\""
-                 "    }, {"
-                 "      \"display_text\": \"D\","
-                 "      \"url\": \"http://www.example.com/3\""
-                 "    }, {"
-                 "      \"display_text\": \"E\","
-                 "      \"url\": \"http://www.example.com/4\""
-                 "    }, {"
-                 "      \"display_text\": \"F\","
-                 "      \"url\": \"http://www.example.com/5\""
-                 "    }, {"
-                 "      \"display_text\": \"G\","
-                 "      \"url\": \"http://www.example.com/6\""
-                 "    } ]"
-                 "  } ]"
-                 "}",
-                 {TestLegalMessageLine(
-                     "aA bB cC dD eE fF gG",
-                     {Link(1, 2, "http://www.example.com/0"),
-                      Link(4, 5, "http://www.example.com/1"),
-                      Link(7, 8, "http://www.example.com/2"),
-                      Link(10, 11, "http://www.example.com/3"),
-                      Link(13, 14, "http://www.example.com/4"),
-                      Link(16, 17, "http://www.example.com/5"),
-                      Link(19, 20, "http://www.example.com/6")})}}));
+        TestCase{
+            "{"
+            "  \"line\" : [ {"
+            "    \"template\": \"a{0} b{1} c{2} d{3} e{4} f{5} g{6}\","
+            "    \"template_parameter\": [ {"
+            "      \"display_text\": \"A\","
+            "      \"url\": \"http://www.example.com/0\""
+            "    }, {"
+            "      \"display_text\": \"B\","
+            "      \"url\": \"http://www.example.com/1\""
+            "    }, {"
+            "      \"display_text\": \"C\","
+            "      \"url\": \"http://www.example.com/2\""
+            "    }, {"
+            "      \"display_text\": \"D\","
+            "      \"url\": \"http://www.example.com/3\""
+            "    }, {"
+            "      \"display_text\": \"E\","
+            "      \"url\": \"http://www.example.com/4\""
+            "    }, {"
+            "      \"display_text\": \"F\","
+            "      \"url\": \"http://www.example.com/5\""
+            "    }, {"
+            "      \"display_text\": \"G\","
+            "      \"url\": \"http://www.example.com/6\""
+            "    } ]"
+            "  } ]"
+            "}",
+            {TestLegalMessageLine("aA bB cC dD eE fF gG",
+                                  {Link(1, 2, "http://www.example.com/0"),
+                                   Link(4, 5, "http://www.example.com/1"),
+                                   Link(7, 8, "http://www.example.com/2"),
+                                   Link(10, 11, "http://www.example.com/3"),
+                                   Link(13, 14, "http://www.example.com/4"),
+                                   Link(16, 17, "http://www.example.com/5"),
+                                   Link(19, 20, "http://www.example.com/6")})}},
+        // When |escape_apostrophes| is true, all ASCII apostrophes should be
+        // escaped for ICU's MessageFormat by doubling them up.  This allows the
+        // template parameters to work correctly.
+        // http://www.icu-project.org/apiref/icu4c/messagepattern_8h.html#af6e0757e0eb81c980b01ee5d68a9978b
+        TestCase{
+            "{"
+            "  \"line\" : [ {"
+            "    \"template\": \"The panda bear's bamboo was '{0}.\","
+            "    \"template_parameter\": [ {"
+            "      \"display_text\": \"delicious\","
+            "      \"url\": \"http://www.example.com/0\""
+            "    } ]"
+            "  } ]"
+            "}",
+            {TestLegalMessageLine("The panda bear's bamboo was 'delicious.",
+                                  {Link(29, 38, "http://www.example.com/0")})},
+            true}));
 
 }  // namespace autofill
diff --git a/components/certificate_reporting/BUILD.gn b/components/certificate_reporting/BUILD.gn
index 74d4887..d4717c2 100644
--- a/components/certificate_reporting/BUILD.gn
+++ b/components/certificate_reporting/BUILD.gn
@@ -21,6 +21,7 @@
   deps = [
     "//base",
     "//components/network_time",
+    "//components/version_info",
     "//crypto",
     "//net",
     "//url",
@@ -52,6 +53,7 @@
     "//components/network_time",
     "//components/network_time:network_time_test_support",
     "//components/prefs:test_support",
+    "//components/version_info",
     "//net:test_support",
     "//testing/gtest",
   ]
diff --git a/components/certificate_reporting/DEPS b/components/certificate_reporting/DEPS
index bb3fb07..89d5a2fd 100644
--- a/components/certificate_reporting/DEPS
+++ b/components/certificate_reporting/DEPS
@@ -1,7 +1,8 @@
 include_rules = [
   "+components/network_time",
   "+components/prefs",
+  "+components/version_info",
   "+crypto",
   "+net",
   "+third_party/boringssl/src/include",
-]
\ No newline at end of file
+]
diff --git a/components/certificate_reporting/cert_logger.proto b/components/certificate_reporting/cert_logger.proto
index 0d4b760..e28b3b9 100644
--- a/components/certificate_reporting/cert_logger.proto
+++ b/components/certificate_reporting/cert_logger.proto
@@ -148,4 +148,16 @@
   // False when the report is attempted to be uploaded for the first time. True
   // in all other uploads.
   optional bool is_retry_upload = 11;
+
+  enum ChromeChannel {
+    CHROME_CHANNEL_NONE = 0;
+    CHROME_CHANNEL_UNKNOWN = 1;
+    CHROME_CHANNEL_DEV = 2;
+    CHROME_CHANNEL_CANARY = 3;
+    CHROME_CHANNEL_BETA = 4;
+    CHROME_CHANNEL_STABLE = 5;
+  };
+
+  // The Chrome channel that this error occurred on.
+  optional ChromeChannel chrome_channel = 12;
 };
diff --git a/components/certificate_reporting/error_report.cc b/components/certificate_reporting/error_report.cc
index ebc41f5..e988ffc 100644
--- a/components/certificate_reporting/error_report.cc
+++ b/components/certificate_reporting/error_report.cc
@@ -9,7 +9,6 @@
 #include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/time/time.h"
-#include "components/certificate_reporting/cert_logger.pb.h"
 #include "components/network_time/network_time_tracker.h"
 #include "net/cert/cert_status_flags.h"
 #include "net/cert/x509_certificate.h"
@@ -174,6 +173,33 @@
   network_time_info->set_network_time_query_behavior(report_behavior);
 }
 
+void ErrorReport::AddChromeChannel(version_info::Channel channel) {
+  switch (channel) {
+    case version_info::Channel::STABLE:
+      cert_report_->set_chrome_channel(
+          CertLoggerRequest::CHROME_CHANNEL_STABLE);
+      break;
+
+    case version_info::Channel::BETA:
+      cert_report_->set_chrome_channel(CertLoggerRequest::CHROME_CHANNEL_BETA);
+      break;
+
+    case version_info::Channel::CANARY:
+      cert_report_->set_chrome_channel(
+          CertLoggerRequest::CHROME_CHANNEL_CANARY);
+      break;
+
+    case version_info::Channel::DEV:
+      cert_report_->set_chrome_channel(CertLoggerRequest::CHROME_CHANNEL_DEV);
+      break;
+
+    case version_info::Channel::UNKNOWN:
+      cert_report_->set_chrome_channel(
+          CertLoggerRequest::CHROME_CHANNEL_UNKNOWN);
+      break;
+  }
+}
+
 void ErrorReport::SetIsRetryUpload(bool is_retry_upload) {
   cert_report_->set_is_retry_upload(is_retry_upload);
 }
@@ -182,6 +208,10 @@
   return cert_report_->hostname();
 }
 
+CertLoggerRequest::ChromeChannel ErrorReport::chrome_channel() const {
+  return cert_report_->chrome_channel();
+}
+
 bool ErrorReport::is_retry_upload() const {
   return cert_report_->is_retry_upload();
 }
diff --git a/components/certificate_reporting/error_report.h b/components/certificate_reporting/error_report.h
index 0d611db..801e75e 100644
--- a/components/certificate_reporting/error_report.h
+++ b/components/certificate_reporting/error_report.h
@@ -8,6 +8,9 @@
 #include <memory>
 #include <string>
 
+#include "components/certificate_reporting/cert_logger.pb.h"
+#include "components/version_info/version_info.h"
+
 namespace base {
 class Time;
 }  // namespace base
@@ -73,12 +76,17 @@
   void AddNetworkTimeInfo(
       const network_time::NetworkTimeTracker* network_time_tracker);
 
+  void AddChromeChannel(version_info::Channel channel);
+
   // Sets is_retry_upload field of the protobuf to |is_retry_upload|.
   void SetIsRetryUpload(bool is_retry_upload);
 
   // Gets the hostname to which this report corresponds.
   const std::string& hostname() const;
 
+  // Gets the Chrome channel attached to this report.
+  CertLoggerRequest::ChromeChannel chrome_channel() const;
+
   // Returns true if the report has been retried.
   bool is_retry_upload() const;
 
diff --git a/components/certificate_reporting/error_report_unittest.cc b/components/certificate_reporting/error_report_unittest.cc
index 03667c5..5818625 100644
--- a/components/certificate_reporting/error_report_unittest.cc
+++ b/components/certificate_reporting/error_report_unittest.cc
@@ -18,6 +18,7 @@
 #include "components/certificate_reporting/cert_logger.pb.h"
 #include "components/network_time/network_time_test_utils.h"
 #include "components/prefs/testing_pref_service.h"
+#include "components/version_info/version_info.h"
 #include "net/cert/cert_status_flags.h"
 #include "net/ssl/ssl_info.h"
 #include "net/test/cert_test_util.h"
@@ -247,6 +248,37 @@
                 .network_time_query_behavior());
 }
 
+TEST(ErrorReportTest, TestChromeChannelIncluded) {
+  struct ChannelTestCase {
+    version_info::Channel channel;
+    CertLoggerRequest::ChromeChannel expected_channel;
+  } kTestCases[] = {
+      {version_info::Channel::UNKNOWN,
+       CertLoggerRequest::CHROME_CHANNEL_UNKNOWN},
+      {version_info::Channel::DEV, CertLoggerRequest::CHROME_CHANNEL_DEV},
+      {version_info::Channel::CANARY, CertLoggerRequest::CHROME_CHANNEL_CANARY},
+      {version_info::Channel::BETA, CertLoggerRequest::CHROME_CHANNEL_BETA},
+      {version_info::Channel::STABLE,
+       CertLoggerRequest::CHROME_CHANNEL_STABLE}};
+
+  // Create a report, set its channel value and check if we
+  // get back test_case.expected_channel.
+  for (const ChannelTestCase& test_case : kTestCases) {
+    SSLInfo ssl_info;
+    ASSERT_NO_FATAL_FAILURE(
+        GetTestSSLInfo(INCLUDE_UNVERIFIED_CERT_CHAIN, &ssl_info, kCertStatus));
+    ErrorReport report(kDummyHostname, ssl_info);
+
+    report.AddChromeChannel(test_case.channel);
+    std::string serialized_report;
+    ASSERT_TRUE(report.Serialize(&serialized_report));
+
+    CertLoggerRequest parsed;
+    ASSERT_TRUE(parsed.ParseFromString(serialized_report));
+    EXPECT_EQ(test_case.expected_channel, parsed.chrome_channel());
+  }
+}
+
 #if defined(OS_ANDROID)
 // Tests that information about the Android AIA fetching feature is included in
 // the report.
diff --git a/components/cronet/ios/cronet_environment.h b/components/cronet/ios/cronet_environment.h
index bed027b..31cec890 100644
--- a/components/cronet/ios/cronet_environment.h
+++ b/components/cronet/ios/cronet_environment.h
@@ -29,7 +29,7 @@
 namespace net {
 class CookieStore;
 class NetLog;
-class WriteToFileNetLogObserver;
+class FileNetLogObserver;
 }  // namespace net
 
 namespace cronet {
@@ -131,7 +131,7 @@
                                     const base::Closure& task);
 
   // Helper methods that start/stop net logging on the network thread.
-  void StartNetLogOnNetworkThread(base::ScopedFILE file, bool log_bytes);
+  void StartNetLogOnNetworkThread(const base::FilePath&, bool log_bytes);
   void StopNetLogOnNetworkThread(base::WaitableEvent* log_stopped_event);
 
   // Returns the HttpNetworkSession object from the passed in
@@ -169,7 +169,7 @@
   std::string user_agent_;
   bool user_agent_partial_;
   std::unique_ptr<net::NetLog> net_log_;
-  std::unique_ptr<net::WriteToFileNetLogObserver> net_log_observer_;
+  std::unique_ptr<net::FileNetLogObserver> file_net_log_observer_;
   bool enable_pkp_bypass_for_local_trust_anchors_;
 
   DISALLOW_COPY_AND_ASSIGN(CronetEnvironment);
diff --git a/components/cronet/ios/cronet_environment.mm b/components/cronet/ios/cronet_environment.mm
index 1688e6d..2379378 100644
--- a/components/cronet/ios/cronet_environment.mm
+++ b/components/cronet/ios/cronet_environment.mm
@@ -8,6 +8,7 @@
 
 #include "base/at_exit.h"
 #include "base/atomicops.h"
+#include "base/bind.h"
 #include "base/command_line.h"
 #include "base/feature_list.h"
 #include "base/files/file_path.h"
@@ -37,9 +38,9 @@
 #include "net/http/http_stream_factory.h"
 #include "net/http/http_transaction_factory.h"
 #include "net/http/http_util.h"
+#include "net/log/file_net_log_observer.h"
 #include "net/log/net_log.h"
 #include "net/log/net_log_capture_mode.h"
-#include "net/log/write_to_file_net_log_observer.h"
 #include "net/proxy/proxy_service.h"
 #include "net/quic/core/quic_versions.h"
 #include "net/socket/ssl_client_socket.h"
@@ -86,6 +87,18 @@
   DISALLOW_COPY_AND_ASSIGN(CronetURLRequestContextGetter);
 };
 
+void SignalEvent(base::WaitableEvent* event) {
+  event->Signal();
+}
+
+// TODO(eroman): Creating the file(s) for a netlog is an internal detail for
+// FileNetLogObsever. This code assumes that the unbounded format is being used,
+// which writes a single file at |path| (creating or overwriting it).
+bool IsNetLogPathValid(const base::FilePath& path) {
+  base::ScopedFILE file(base::OpenFile(path, "w"));
+  return !!file;
+}
+
 }  // namespace
 
 namespace cronet {
@@ -141,42 +154,39 @@
 
 bool CronetEnvironment::StartNetLog(base::FilePath::StringType file_name,
                                     bool log_bytes) {
-  if (!file_name.length())
+  if (file_name.empty())
     return false;
 
   base::FilePath path(file_name);
-
-  base::ScopedFILE file(base::OpenFile(path, "w"));
-  if (!file) {
+  if (!IsNetLogPathValid(path)) {
     LOG(ERROR) << "Can not start NetLog to " << path.value() << ": "
                << strerror(errno);
     return false;
   }
 
   LOG(WARNING) << "Starting NetLog to " << path.value();
-  PostToNetworkThread(
-      FROM_HERE,
-      base::Bind(&CronetEnvironment::StartNetLogOnNetworkThread,
-                 base::Unretained(this), base::Passed(&file), log_bytes));
+  PostToNetworkThread(FROM_HERE,
+                      base::Bind(&CronetEnvironment::StartNetLogOnNetworkThread,
+                                 base::Unretained(this), path, log_bytes));
 
   return true;
 }
 
-void CronetEnvironment::StartNetLogOnNetworkThread(base::ScopedFILE file,
+void CronetEnvironment::StartNetLogOnNetworkThread(const base::FilePath& path,
                                                    bool log_bytes) {
   DCHECK(net_log_);
 
-  if (net_log_observer_)
+  if (file_net_log_observer_)
     return;
 
   net::NetLogCaptureMode capture_mode =
       log_bytes ? net::NetLogCaptureMode::IncludeSocketBytes()
                 : net::NetLogCaptureMode::Default();
 
-  net_log_observer_.reset(new net::WriteToFileNetLogObserver());
-  net_log_observer_->set_capture_mode(capture_mode);
-  net_log_observer_->StartObserving(main_context_->net_log(), std::move(file),
-                                    nullptr, main_context_.get());
+  file_net_log_observer_ =
+      net::FileNetLogObserver::CreateUnbounded(path, nullptr);
+  file_net_log_observer_->StartObserving(main_context_->net_log(),
+                                         capture_mode);
   LOG(WARNING) << "Started NetLog";
 }
 
@@ -192,12 +202,14 @@
 
 void CronetEnvironment::StopNetLogOnNetworkThread(
     base::WaitableEvent* log_stopped_event) {
-  if (net_log_observer_) {
+  if (file_net_log_observer_) {
     DLOG(WARNING) << "Stopped NetLog.";
-    net_log_observer_->StopObserving(main_context_.get());
-    net_log_observer_.reset();
+    file_net_log_observer_->StopObserving(
+        nullptr, base::BindOnce(&SignalEvent, log_stopped_event));
+    file_net_log_observer_.reset();
+  } else {
+    log_stopped_event->Signal();
   }
-  log_stopped_event->Signal();
 }
 
 net::HttpNetworkSession* CronetEnvironment::GetHttpNetworkSession(
diff --git a/components/cronet/ios/test/cronet_netlog_test.mm b/components/cronet/ios/test/cronet_netlog_test.mm
index 71b05b9..3455e46 100644
--- a/components/cronet/ios/test/cronet_netlog_test.mm
+++ b/components/cronet/ios/test/cronet_netlog_test.mm
@@ -39,6 +39,7 @@
   NSString* filename = [[[NSProcessInfo processInfo] globallyUniqueString]
       stringByAppendingString:@"_netlog.json"];
   bool netlog_started = [Cronet startNetLogToFile:filename logBytes:YES];
+  [Cronet stopNetLog];
 
   bool file_created = [[NSFileManager defaultManager]
       fileExistsAtPath:[Cronet getNetLogPathForFile:filename]];
@@ -72,6 +73,8 @@
       [Cronet startNetLogToFile:[dir stringByAppendingString:@"/netlog.json"]
                        logBytes:NO];
 
+  [Cronet stopNetLog];
+
   [[NSFileManager defaultManager]
       removeItemAtPath:[Cronet
                            getNetLogPathForFile:
diff --git a/components/cryptauth/cryptauth_client.h b/components/cryptauth/cryptauth_client.h
index 6779bfb8..1fe98a9 100644
--- a/components/cryptauth/cryptauth_client.h
+++ b/components/cryptauth/cryptauth_client.h
@@ -25,6 +25,8 @@
 class SetupEnrollmentResponse;
 class FinishEnrollmentRequest;
 class FinishEnrollmentResponse;
+class FindEligibleForPromotionRequest;
+class FindEligibleForPromotionResponse;
 }
 
 namespace cryptauth {
@@ -59,6 +61,14 @@
       const FindEligibleUnlockDevicesCallback& callback,
       const ErrorCallback& error_callback) = 0;
 
+  // FindEligibleForPromotion
+  typedef base::Callback<void(const FindEligibleForPromotionResponse&)>
+      FindEligibleForPromotionCallback;
+  virtual void FindEligibleForPromotion(
+      const FindEligibleForPromotionRequest& request,
+      const FindEligibleForPromotionCallback& callback,
+      const ErrorCallback& error_callback) = 0;
+
   // SendDeviceSyncTickle
   typedef base::Callback<void(const SendDeviceSyncTickleResponse&)>
       SendDeviceSyncTickleCallback;
diff --git a/components/cryptauth/cryptauth_client_impl.cc b/components/cryptauth/cryptauth_client_impl.cc
index 92756ea..8fbe82e0 100644
--- a/components/cryptauth/cryptauth_client_impl.cc
+++ b/components/cryptauth/cryptauth_client_impl.cc
@@ -26,6 +26,8 @@
 const char kGetMyDevicesPath[] = "deviceSync/getmydevices";
 const char kFindEligibleUnlockDevicesPath[] =
     "deviceSync/findeligibleunlockdevices";
+const char kFindEligibleForPromotionPath[] =
+    "deviceSync/findeligibleforpromotion";
 const char kSendDeviceSyncTicklePath[] = "deviceSync/senddevicesynctickle";
 const char kToggleEasyUnlockPath[] = "deviceSync/toggleeasyunlock";
 const char kSetupEnrollmentPath[] = "enrollment/setup";
@@ -105,6 +107,36 @@
               partial_traffic_annotation);
 }
 
+void CryptAuthClientImpl::FindEligibleForPromotion(
+    const FindEligibleForPromotionRequest& request,
+    const FindEligibleForPromotionCallback& callback,
+    const ErrorCallback& error_callback) {
+  net::PartialNetworkTrafficAnnotationTag partial_traffic_annotation =
+      net::DefinePartialNetworkTrafficAnnotation(
+          "cryptauth_find_eligible_for_promotion", "oauth2_api_call_flow",
+          R"(
+      semantics {
+        sender: "Promotion Manager"
+        description:
+          "Return whether the current device is eligible for a Smart Lock promotion."
+        trigger:
+          "This request is sent when the user starts the Smart Lock setup flow."
+        data: "OAuth 2.0 token and the device's public key."
+        destination: GOOGLE_OWNED_SERVICE
+      }
+      policy {
+        setting:
+          "This feature cannot be disabled in settings"
+        chrome_policy {
+          EasyUnlockAllowed {
+            EasyUnlockAllowed: false
+          }
+        }
+      })");
+  MakeApiCall(kFindEligibleForPromotionPath, request, callback, error_callback,
+              partial_traffic_annotation);
+}
+
 void CryptAuthClientImpl::SendDeviceSyncTickle(
     const SendDeviceSyncTickleRequest& request,
     const SendDeviceSyncTickleCallback& callback,
diff --git a/components/cryptauth/cryptauth_client_impl.h b/components/cryptauth/cryptauth_client_impl.h
index 31d7ddf0..3ccea85 100644
--- a/components/cryptauth/cryptauth_client_impl.h
+++ b/components/cryptauth/cryptauth_client_impl.h
@@ -47,6 +47,10 @@
       const FindEligibleUnlockDevicesRequest& request,
       const FindEligibleUnlockDevicesCallback& callback,
       const ErrorCallback& error_callback) override;
+  void FindEligibleForPromotion(
+      const FindEligibleForPromotionRequest& request,
+      const FindEligibleForPromotionCallback& callback,
+      const ErrorCallback& error_callback) override;
   void SendDeviceSyncTickle(const SendDeviceSyncTickleRequest& request,
                             const SendDeviceSyncTickleCallback& callback,
                             const ErrorCallback& error_callback,
diff --git a/components/cryptauth/cryptauth_client_impl_unittest.cc b/components/cryptauth/cryptauth_client_impl_unittest.cc
index 4a012ec..bcf4be2 100644
--- a/components/cryptauth/cryptauth_client_impl_unittest.cc
+++ b/components/cryptauth/cryptauth_client_impl_unittest.cc
@@ -276,6 +276,24 @@
   EXPECT_EQ(kStatus403Error, error_message);
 }
 
+TEST_F(CryptAuthClientTest, FindEligibleForPromotionSuccess) {
+  ExpectRequest(
+      "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
+      "findeligibleforpromotion?alt=proto");
+
+  FindEligibleForPromotionResponse result_proto;
+  client_->FindEligibleForPromotion(
+      FindEligibleForPromotionRequest(),
+      base::Bind(&SaveResult<FindEligibleForPromotionResponse>, &result_proto),
+      base::Bind(&NotCalled<std::string>));
+
+  FindEligibleForPromotionRequest expected_request;
+  EXPECT_TRUE(expected_request.ParseFromString(serialized_request_));
+
+  FindEligibleForPromotionResponse response_proto;
+  FinishApiCallFlow(&response_proto);
+}
+
 TEST_F(CryptAuthClientTest, SendDeviceSyncTickleSuccess) {
   ExpectRequest(
       "https://www.testgoogleapis.com/cryptauth/v1/deviceSync/"
diff --git a/components/cryptauth/mock_cryptauth_client.h b/components/cryptauth/mock_cryptauth_client.h
index d5d3b24..d4df4640 100644
--- a/components/cryptauth/mock_cryptauth_client.h
+++ b/components/cryptauth/mock_cryptauth_client.h
@@ -29,6 +29,10 @@
                void(const FindEligibleUnlockDevicesRequest& request,
                     const FindEligibleUnlockDevicesCallback& callback,
                     const ErrorCallback& error_callback));
+  MOCK_METHOD3(FindEligibleForPromotion,
+               void(const FindEligibleForPromotionRequest& request,
+                    const FindEligibleForPromotionCallback& callback,
+                    const ErrorCallback& error_callback));
   MOCK_METHOD4(SendDeviceSyncTickle,
                void(const SendDeviceSyncTickleRequest& request,
                     const SendDeviceSyncTickleCallback& callback,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
index 72ba804..bfeeb16 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_compression_stats.cc
@@ -1078,6 +1078,7 @@
         long_bypass.Add(data_used);
         break;
       case UPDATE:
+      case DIRECT_HTTP:
         // Don't record any request level prefs. If this is an update, this data
         // was already recorded at the URLRequest level. Updates are generally
         // page load level optimizations and don't correspond to request types.
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.cc
index cfe96f4b..53e11eb 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.cc
@@ -29,27 +29,11 @@
     return UNKNOWN_TYPE;
   }
 
-  // Check if the request came through the Data Reduction Proxy before checking
-  // if proxies are bypassed, to avoid misreporting cases where the Data
-  // Reduction Proxy was bypassed between the request being sent out and the
-  // response coming in. For 304 responses, check if the request was sent to the
-  // Data Reduction Proxy, since 304s aren't required to have a Via header even
-  // if they came through the Data Reduction Proxy.
   if (request.response_headers() &&
-      (HasDataReductionProxyViaHeader(*request.response_headers(), nullptr) ||
-       (request.response_headers()->response_code() == net::HTTP_NOT_MODIFIED &&
-        config.WasDataReductionProxyUsed(&request, nullptr)))) {
+      HasDataReductionProxyViaHeader(*request.response_headers(), nullptr)) {
     return VIA_DATA_REDUCTION_PROXY;
   }
 
-  base::TimeDelta bypass_delay;
-  if (config.AreDataReductionProxiesBypassed(
-      request, data_reduction_proxy_config, &bypass_delay)) {
-    if (bypass_delay > base::TimeDelta::FromSeconds(kLongBypassDelayInSeconds))
-      return LONG_BYPASS;
-    return SHORT_BYPASS;
-  }
-
   // Treat bypasses that only apply to the individual request as SHORT_BYPASS.
   // This includes bypasses triggered by "Chrome-Proxy: block-once", bypasses
   // due to other proxies overriding the Data Reduction Proxy, and bypasses due
@@ -63,6 +47,31 @@
     return SHORT_BYPASS;
   }
 
+  if (request.proxy_server().is_direct() ||
+      !request.proxy_server().is_valid()) {
+    return DIRECT_HTTP;
+  }
+
+  base::TimeDelta bypass_delay;
+  if (config.AreDataReductionProxiesBypassed(
+          request, data_reduction_proxy_config, &bypass_delay)) {
+    if (bypass_delay > base::TimeDelta::FromSeconds(kLongBypassDelayInSeconds))
+      return LONG_BYPASS;
+    return SHORT_BYPASS;
+  }
+
+  // Check if the request came through the Data Reduction Proxy before checking
+  // if proxies are bypassed, to avoid misreporting cases where the Data
+  // Reduction Proxy was bypassed between the request being sent out and the
+  // response coming in. For 304 responses, check if the request was sent to the
+  // Data Reduction Proxy, since 304s aren't required to have a Via header even
+  // if they came through the Data Reduction Proxy.
+  if (request.response_headers() &&
+      request.response_headers()->response_code() == net::HTTP_NOT_MODIFIED &&
+      config.WasDataReductionProxyUsed(&request, nullptr)) {
+    return VIA_DATA_REDUCTION_PROXY;
+  }
+
   return UNKNOWN_TYPE;
 }
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h
index c1ff065..9c52af5 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics.h
@@ -40,6 +40,7 @@
   LONG_BYPASS,   // The client is bypassed by the proxy for a long time (due
                  // to country bypass policy, for example).
   UPDATE,        // An update to already counted request data.
+  DIRECT_HTTP,   // An http request with a disabled data reduction proxy.
   UNKNOWN_TYPE,  // Any other reason not listed above.
 };
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc
index 9f6df6c..3eaf9e5b 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_metrics_unittest.cc
@@ -68,24 +68,40 @@
       {
           GURL("http://foo.com"), net::ProxyServer::Direct(),
           base::TimeDelta::FromSeconds(1), net::LOAD_NORMAL,
-          "HTTP/1.1 200 OK\r\n\r\n", SHORT_BYPASS,
+          "HTTP/1.1 200 OK\r\n\r\n", DIRECT_HTTP,
       },
       {
           GURL("http://foo.com"), net::ProxyServer::Direct(),
           base::TimeDelta::FromSeconds(1), net::LOAD_NORMAL,
-          "HTTP/1.1 304 Not Modified\r\n\r\n", SHORT_BYPASS,
+          "HTTP/1.1 304 Not Modified\r\n\r\n", DIRECT_HTTP,
       },
       {
           GURL("http://foo.com"), net::ProxyServer::Direct(),
           base::TimeDelta::FromMinutes(60), net::LOAD_NORMAL,
-          "HTTP/1.1 200 OK\r\n\r\n", LONG_BYPASS,
+          "HTTP/1.1 200 OK\r\n\r\n", DIRECT_HTTP,
       },
       {
           GURL("http://foo.com"), net::ProxyServer::Direct(),
           base::TimeDelta::FromMinutes(60), net::LOAD_NORMAL,
-          "HTTP/1.1 304 Not Modified\r\n\r\n", LONG_BYPASS,
+          "HTTP/1.1 304 Not Modified\r\n\r\n", DIRECT_HTTP,
       },
-      // Requests with LOAD_BYPASS_PROXY (e.g. block-once) should be classified
+      {
+          GURL("http://foo.com"), origin, base::TimeDelta::FromSeconds(1),
+          net::LOAD_NORMAL, "HTTP/1.1 200 OK\r\n\r\n", SHORT_BYPASS,
+      },
+      {
+          GURL("http://foo.com"), origin, base::TimeDelta::FromSeconds(1),
+          net::LOAD_NORMAL, "HTTP/1.1 304 Not Modified\r\n\r\n", SHORT_BYPASS,
+      },
+      {
+          GURL("http://foo.com"), origin, base::TimeDelta::FromMinutes(60),
+          net::LOAD_NORMAL, "HTTP/1.1 200 OK\r\n\r\n", LONG_BYPASS,
+      },
+      {
+          GURL("http://foo.com"), origin, base::TimeDelta::FromMinutes(60),
+          net::LOAD_NORMAL, "HTTP/1.1 304 Not Modified\r\n\r\n", LONG_BYPASS,
+      },  // Requests with LOAD_BYPASS_PROXY (e.g. block-once) should be
+          // classified
       // as SHORT_BYPASS.
       {
           GURL("http://foo.com"), net::ProxyServer::Direct(), base::TimeDelta(),
@@ -106,12 +122,12 @@
           base::TimeDelta(), net::LOAD_NORMAL, "HTTP/1.1 200 OK\r\n\r\n",
           SHORT_BYPASS,
       },
-      // Responses that seem like they should have come through the Data
-      // Reduction Proxy, but did not, should be classified as UNKNOWN_TYPE.
       {
           GURL("http://foo.com"), net::ProxyServer::Direct(), base::TimeDelta(),
-          net::LOAD_NORMAL, "HTTP/1.1 200 OK\r\n\r\n", UNKNOWN_TYPE,
+          net::LOAD_NORMAL, "HTTP/1.1 200 OK\r\n\r\n", DIRECT_HTTP,
       },
+      // Responses that seem like they should have come through the Data
+      // Reduction Proxy, but did not, should be classified as UNKNOWN_TYPE.
       {
           GURL("http://foo.com"), origin, base::TimeDelta(), net::LOAD_NORMAL,
           "HTTP/1.1 200 OK\r\n\r\n", UNKNOWN_TYPE,
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
index 12d3470d..7bc850a 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc
@@ -84,6 +84,7 @@
       suffix = ".ViaDRP";
       break;
     case HTTPS:
+    case DIRECT_HTTP:
       suffix = ".Direct";
       break;
     case SHORT_BYPASS:
@@ -150,9 +151,10 @@
   UMA_HISTOGRAM_COUNTS_1M("Net.HttpContentLength", received_content_length);
 
   // Record the new histograms broken down by HTTP/HTTPS and video/non-video
-  RecordNewContentLengthHistograms("Net.HttpContentLength", is_https, is_video,
-                                   request_type, received_content_length);
-  RecordNewContentLengthHistograms("Net.HttpOriginalContentLength", is_https,
+  RecordNewContentLengthHistograms("Net.HttpContentLengthV2", is_https,
+                                   is_video, request_type,
+                                   received_content_length);
+  RecordNewContentLengthHistograms("Net.HttpOriginalContentLengthV2", is_https,
                                    is_video, request_type,
                                    original_content_length);
 
diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
index 30ce6c4..dcc2cfe 100644
--- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
+++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc
@@ -90,40 +90,40 @@
 
 // HTTP original content length
 const char kOriginalInsecureDirectHistogramName[] =
-    "Net.HttpOriginalContentLength.Http.Direct";
+    "Net.HttpOriginalContentLengthV2.Http.Direct";
 const char kOriginalInsecureViaDRPHistogramName[] =
-    "Net.HttpOriginalContentLength.Http.ViaDRP";
+    "Net.HttpOriginalContentLengthV2.Http.ViaDRP";
 const char kOriginalInsecureBypassedHistogramName[] =
-    "Net.HttpOriginalContentLength.Http.BypassedDRP";
+    "Net.HttpOriginalContentLengthV2.Http.BypassedDRP";
 const char kOriginalInsecureOtherHistogramName[] =
-    "Net.HttpOriginalContentLength.Http.Other";
+    "Net.HttpOriginalContentLengthV2.Http.Other";
 // HTTP video original content length
 const char kOriginalVideoInsecureDirectHistogramName[] =
-    "Net.HttpOriginalContentLength.Http.Direct.Video";
+    "Net.HttpOriginalContentLengthV2.Http.Direct.Video";
 const char kOriginalVideoInsecureViaDRPHistogramName[] =
-    "Net.HttpOriginalContentLength.Http.ViaDRP.Video";
+    "Net.HttpOriginalContentLengthV2.Http.ViaDRP.Video";
 const char kOriginalVideoInsecureBypassedHistogramName[] =
-    "Net.HttpOriginalContentLength.Http.BypassedDRP.Video";
+    "Net.HttpOriginalContentLengthV2.Http.BypassedDRP.Video";
 const char kOriginalVideoInsecureOtherHistogramName[] =
-    "Net.HttpOriginalContentLength.Http.Other.Video";
+    "Net.HttpOriginalContentLengthV2.Http.Other.Video";
 // HTTPS original content length
 const char kOriginalSecureDirectHistogramName[] =
-    "Net.HttpOriginalContentLength.Https.Direct";
+    "Net.HttpOriginalContentLengthV2.Https.Direct";
 const char kOriginalSecureViaDRPHistogramName[] =
-    "Net.HttpOriginalContentLength.Https.ViaDRP";
+    "Net.HttpOriginalContentLengthV2.Https.ViaDRP";
 const char kOriginalSecureBypassedHistogramName[] =
-    "Net.HttpOriginalContentLength.Https.BypassedDRP";
+    "Net.HttpOriginalContentLengthV2.Https.BypassedDRP";
 const char kOriginalSecureOtherHistogramName[] =
-    "Net.HttpOriginalContentLength.Https.Other";
+    "Net.HttpOriginalContentLengthV2.Https.Other";
 // HTTPS video original content length
 const char kOriginalVideoSecureDirectHistogramName[] =
-    "Net.HttpOriginalContentLength.Https.Direct.Video";
+    "Net.HttpOriginalContentLengthV2.Https.Direct.Video";
 const char kOriginalVideoSecureViaDRPHistogramName[] =
-    "Net.HttpOriginalContentLength.Https.ViaDRP.Video";
+    "Net.HttpOriginalContentLengthV2.Https.ViaDRP.Video";
 const char kOriginalVideoSecureBypassedHistogramName[] =
-    "Net.HttpOriginalContentLength.Https.BypassedDRP.Video";
+    "Net.HttpOriginalContentLengthV2.Https.BypassedDRP.Video";
 const char kOriginalVideoSecureOtherHistogramName[] =
-    "Net.HttpOriginalContentLength.Https.Other.Video";
+    "Net.HttpOriginalContentLengthV2.Https.Other.Video";
 
 // Lo-Fi histograms.
 const char kReceivedValidOCLLoFiOnHistogramName[] =
@@ -135,37 +135,37 @@
 
 const char kReceivedHistogramName[] = "Net.HttpContentLength";
 const char kReceivedInsecureDirectHistogramName[] =
-    "Net.HttpContentLength.Http.Direct";
+    "Net.HttpContentLengthV2.Http.Direct";
 const char kReceivedInsecureViaDRPHistogramName[] =
-    "Net.HttpContentLength.Http.ViaDRP";
+    "Net.HttpContentLengthV2.Http.ViaDRP";
 const char kReceivedInsecureBypassedHistogramName[] =
-    "Net.HttpContentLength.Http.BypassedDRP";
+    "Net.HttpContentLengthV2.Http.BypassedDRP";
 const char kReceivedInsecureOtherHistogramName[] =
-    "Net.HttpContentLength.Http.Other";
+    "Net.HttpContentLengthV2.Http.Other";
 const char kReceivedSecureDirectHistogramName[] =
-    "Net.HttpContentLength.Https.Direct";
+    "Net.HttpContentLengthV2.Https.Direct";
 const char kReceivedSecureViaDRPHistogramName[] =
-    "Net.HttpContentLength.Https.ViaDRP";
+    "Net.HttpContentLengthV2.Https.ViaDRP";
 const char kReceivedSecureBypassedHistogramName[] =
-    "Net.HttpContentLength.Https.BypassedDRP";
+    "Net.HttpContentLengthV2.Https.BypassedDRP";
 const char kReceivedSecureOtherHistogramName[] =
-    "Net.HttpContentLength.Https.Other";
+    "Net.HttpContentLengthV2.Https.Other";
 const char kReceivedVideoInsecureDirectHistogramName[] =
-    "Net.HttpContentLength.Http.Direct.Video";
+    "Net.HttpContentLengthV2.Http.Direct.Video";
 const char kReceivedVideoInsecureViaDRPHistogramName[] =
-    "Net.HttpContentLength.Http.ViaDRP.Video";
+    "Net.HttpContentLengthV2.Http.ViaDRP.Video";
 const char kReceivedVideoInsecureBypassedHistogramName[] =
-    "Net.HttpContentLength.Http.BypassedDRP.Video";
+    "Net.HttpContentLengthV2.Http.BypassedDRP.Video";
 const char kReceivedVideoInsecureOtherHistogramName[] =
-    "Net.HttpContentLength.Http.Other.Video";
+    "Net.HttpContentLengthV2.Http.Other.Video";
 const char kReceivedVideoSecureDirectHistogramName[] =
-    "Net.HttpContentLength.Https.Direct.Video";
+    "Net.HttpContentLengthV2.Https.Direct.Video";
 const char kReceivedVideoSecureViaDRPHistogramName[] =
-    "Net.HttpContentLength.Https.ViaDRP.Video";
+    "Net.HttpContentLengthV2.Https.ViaDRP.Video";
 const char kReceivedVideoSecureBypassedHistogramName[] =
-    "Net.HttpContentLength.Https.BypassedDRP.Video";
+    "Net.HttpContentLengthV2.Https.BypassedDRP.Video";
 const char kReceivedVideoSecureOtherHistogramName[] =
-    "Net.HttpContentLength.Https.Other.Video";
+    "Net.HttpContentLengthV2.Https.Other.Video";
 const char kOriginalHistogramName[] = "Net.HttpOriginalContentLength";
 const char kDifferenceHistogramName[] = "Net.HttpContentLengthDifference";
 const char kFreshnessLifetimeHistogramName[] =
@@ -1538,8 +1538,8 @@
        kOriginalContentLength,
        kResponseContentLength,
        {
-           {kReceivedInsecureOtherHistogramName, kResponseContentLength},
-           {kOriginalInsecureOtherHistogramName, kResponseContentLength},
+           {kReceivedInsecureDirectHistogramName, kResponseContentLength},
+           {kOriginalInsecureDirectHistogramName, kResponseContentLength},
        }},
       {"DRP not configured for http video",
        true,
@@ -1548,10 +1548,10 @@
        kOriginalContentLength,
        kResponseContentLength,
        {
-           {kReceivedInsecureOtherHistogramName, kResponseContentLength},
-           {kOriginalInsecureOtherHistogramName, kResponseContentLength},
-           {kReceivedVideoInsecureOtherHistogramName, kResponseContentLength},
-           {kOriginalVideoInsecureOtherHistogramName, kResponseContentLength},
+           {kReceivedInsecureDirectHistogramName, kResponseContentLength},
+           {kOriginalInsecureDirectHistogramName, kResponseContentLength},
+           {kReceivedVideoInsecureDirectHistogramName, kResponseContentLength},
+           {kOriginalVideoInsecureDirectHistogramName, kResponseContentLength},
        }},
       {"nonvideo over https",
        false,
diff --git a/components/download/internal/controller_impl.cc b/components/download/internal/controller_impl.cc
index cd69bdda..fc272a6 100644
--- a/components/download/internal/controller_impl.cc
+++ b/components/download/internal/controller_impl.cc
@@ -437,6 +437,12 @@
   if (!startup_status_.Ok()) {
     // TODO(dtrainor): Recover here.  Try to clean up any disk state and, if
     // possible, any DownloadDriver data and continue with initialization?
+
+    // If we cannot recover, notify Clients that the service is unavailable.
+    base::ThreadTaskRunnerHandle::Get()->PostTask(
+        FROM_HERE, base::Bind(&ControllerImpl::SendOnServiceUnavailable,
+                              weak_ptr_factory_.GetWeakPtr()));
+
     ProcessScheduledTasks();
     return;
   }
@@ -446,6 +452,7 @@
   CancelOrphanedRequests();
   CleanupUnknownFiles();
   ResolveInitialRequestStates();
+
   NotifyClientsOfStartup();
 
   initializing_internals_ = false;
@@ -472,11 +479,11 @@
   auto entries = model_->PeekEntries();
 
   std::vector<std::string> guids_to_remove;
-  std::vector<base::FilePath> files_to_remove;
+  std::set<base::FilePath> files_to_remove;
   for (auto* entry : entries) {
     if (!clients_->GetClient(entry->client)) {
       guids_to_remove.push_back(entry->guid);
-      files_to_remove.push_back(entry->target_file_path);
+      files_to_remove.insert(entry->target_file_path);
     }
   }
 
@@ -864,6 +871,12 @@
   client->OnServiceInitialized(guids);
 }
 
+void ControllerImpl::SendOnServiceUnavailable() {
+  for (auto client_id : clients_->GetRegisteredClients()) {
+    clients_->GetClient(client_id)->OnServiceUnavailable();
+  }
+}
+
 void ControllerImpl::SendOnDownloadUpdated(DownloadClient client_id,
                                            const std::string& guid,
                                            uint64_t bytes_downloaded) {
diff --git a/components/download/internal/controller_impl.h b/components/download/internal/controller_impl.h
index 387882b..554bce8 100644
--- a/components/download/internal/controller_impl.h
+++ b/components/download/internal/controller_impl.h
@@ -156,6 +156,7 @@
   // meant to help prevent reentrancy.
   void SendOnServiceInitialized(DownloadClient client_id,
                                 const std::vector<std::string>& guids);
+  void SendOnServiceUnavailable();
   void SendOnDownloadUpdated(DownloadClient client_id,
                              const std::string& guid,
                              uint64_t bytes_downloaded);
diff --git a/components/download/internal/controller_impl_unittest.cc b/components/download/internal/controller_impl_unittest.cc
index 561a482..8b32f27 100644
--- a/components/download/internal/controller_impl_unittest.cc
+++ b/components/download/internal/controller_impl_unittest.cc
@@ -88,8 +88,8 @@
   MOCK_METHOD1(CleanupFilesForCompletedEntries,
                std::vector<Entry*>(const Model::EntryList&));
   MOCK_METHOD2(DeleteFiles,
-               void(const std::vector<base::FilePath>&,
-                    stats::FileCleanupReason));
+               void(const std::set<base::FilePath>&, stats::FileCleanupReason));
+  MOCK_METHOD1(HardRecover, void(const FileMonitor::InitCallback&));
 };
 
 void MockFileMonitor::Initialize(const FileMonitor::InitCallback& callback) {
@@ -306,6 +306,7 @@
 
 TEST_F(DownloadServiceControllerImplTest, FailedInitWithBadModel) {
   EXPECT_CALL(*client_, OnServiceInitialized(_)).Times(0);
+  EXPECT_CALL(*client_, OnServiceUnavailable()).Times(1);
 
   controller_->Initialize();
   store_->TriggerInit(false, base::MakeUnique<std::vector<Entry>>());
diff --git a/components/download/internal/file_monitor.h b/components/download/internal/file_monitor.h
index e5179b0..7c98c91 100644
--- a/components/download/internal/file_monitor.h
+++ b/components/download/internal/file_monitor.h
@@ -6,6 +6,7 @@
 #define COMPONENTS_DOWNLOAD_INTERNAL_FILE_MONITOR_H_
 
 #include <memory>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -41,9 +42,13 @@
       const Model::EntryList& entries) = 0;
 
   // Deletes a list of files and logs UMA.
-  virtual void DeleteFiles(const std::vector<base::FilePath>& files_to_remove,
+  virtual void DeleteFiles(const std::set<base::FilePath>& files_to_remove,
                            stats::FileCleanupReason reason) = 0;
 
+  // Deletes all files in the download service directory.  This is a hard reset
+  // on this directory.
+  virtual void HardRecover(const InitCallback& callback) = 0;
+
   virtual ~FileMonitor() = default;
 };
 
diff --git a/components/download/internal/file_monitor_impl.cc b/components/download/internal/file_monitor_impl.cc
index 57232f7..5f1e8f55 100644
--- a/components/download/internal/file_monitor_impl.cc
+++ b/components/download/internal/file_monitor_impl.cc
@@ -26,6 +26,64 @@
   return success;
 }
 
+void GetFilesInDirectory(const base::FilePath& directory,
+                         std::set<base::FilePath>& paths_out) {
+  base::ThreadRestrictions::AssertIOAllowed();
+  base::FileEnumerator file_enumerator(directory, false /* recursive */,
+                                       base::FileEnumerator::FILES);
+
+  for (base::FilePath path = file_enumerator.Next(); !path.value().empty();
+       path = file_enumerator.Next()) {
+    paths_out.insert(path);
+  }
+}
+
+void DeleteFilesOnFileThread(const std::set<base::FilePath>& paths,
+                             stats::FileCleanupReason reason) {
+  base::ThreadRestrictions::AssertIOAllowed();
+  int num_delete_attempted = 0;
+  int num_delete_failed = 0;
+  int num_delete_by_external = 0;
+  for (const base::FilePath& path : paths) {
+    if (!base::PathExists(path)) {
+      num_delete_by_external++;
+      continue;
+    }
+
+    num_delete_attempted++;
+    DCHECK(!base::DirectoryExists(path));
+
+    if (!base::DeleteFile(path, false /* recursive */)) {
+      num_delete_failed++;
+    }
+  }
+
+  stats::LogFileCleanupStatus(reason, num_delete_attempted, num_delete_failed,
+                              num_delete_by_external);
+}
+
+void DeleteUnknownFilesOnFileThread(
+    const base::FilePath& directory,
+    const std::set<base::FilePath>& download_file_paths) {
+  base::ThreadRestrictions::AssertIOAllowed();
+  std::set<base::FilePath> files_in_dir;
+  GetFilesInDirectory(directory, files_in_dir);
+
+  std::set<base::FilePath> files_to_remove =
+      base::STLSetDifference<std::set<base::FilePath>>(files_in_dir,
+                                                       download_file_paths);
+  DeleteFilesOnFileThread(files_to_remove, stats::FileCleanupReason::UNKNOWN);
+}
+
+bool HardRecoverOnFileThread(const base::FilePath& directory) {
+  base::ThreadRestrictions::AssertIOAllowed();
+  std::set<base::FilePath> files_in_dir;
+  GetFilesInDirectory(directory, files_in_dir);
+  DeleteFilesOnFileThread(files_in_dir,
+                          stats::FileCleanupReason::HARD_RECOVERY);
+  return CreateDirectoryIfNotExists(directory);
+}
+
 }  // namespace
 
 FileMonitorImpl::FileMonitorImpl(
@@ -58,79 +116,39 @@
   }
 
   file_thread_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&FileMonitorImpl::DeleteUnknownFilesOnFileThread,
-                            weak_factory_.GetWeakPtr(), download_file_paths));
+      FROM_HERE, base::Bind(&DeleteUnknownFilesOnFileThread, download_file_dir_,
+                            download_file_paths));
 }
 
 std::vector<Entry*> FileMonitorImpl::CleanupFilesForCompletedEntries(
     const Model::EntryList& entries) {
   std::vector<Entry*> entries_to_remove;
-  std::vector<base::FilePath> files_to_remove;
+  std::set<base::FilePath> files_to_remove;
   for (auto* entry : entries) {
     if (!ReadyForCleanup(entry))
       continue;
 
     entries_to_remove.push_back(entry);
-    files_to_remove.push_back(entry->target_file_path);
+    files_to_remove.insert(entry->target_file_path);
   }
 
   file_thread_task_runner_->PostTask(
-      FROM_HERE, base::Bind(&FileMonitorImpl::DeleteFilesOnFileThread,
-                            weak_factory_.GetWeakPtr(), files_to_remove,
+      FROM_HERE, base::Bind(&DeleteFilesOnFileThread, files_to_remove,
                             stats::FileCleanupReason::TIMEOUT));
   return entries_to_remove;
 }
 
 void FileMonitorImpl::DeleteFiles(
-    const std::vector<base::FilePath>& files_to_remove,
+    const std::set<base::FilePath>& files_to_remove,
     stats::FileCleanupReason reason) {
   file_thread_task_runner_->PostTask(
-      FROM_HERE,
-      base::Bind(&FileMonitorImpl::DeleteFilesOnFileThread,
-                 weak_factory_.GetWeakPtr(), files_to_remove, reason));
+      FROM_HERE, base::Bind(&DeleteFilesOnFileThread, files_to_remove, reason));
 }
 
-void FileMonitorImpl::DeleteUnknownFilesOnFileThread(
-    const std::set<base::FilePath>& download_file_paths) {
-  base::ThreadRestrictions::AssertIOAllowed();
-  std::set<base::FilePath> files_in_dir;
-  base::FileEnumerator file_enumerator(
-      download_file_dir_, false /* recursive */, base::FileEnumerator::FILES);
-
-  for (base::FilePath path = file_enumerator.Next(); !path.value().empty();
-       path = file_enumerator.Next()) {
-    files_in_dir.insert(path);
-  }
-
-  std::vector<base::FilePath> files_to_remove =
-      base::STLSetDifference<std::vector<base::FilePath>>(files_in_dir,
-                                                          download_file_paths);
-  DeleteFilesOnFileThread(files_to_remove, stats::FileCleanupReason::UNKNOWN);
-}
-
-void FileMonitorImpl::DeleteFilesOnFileThread(
-    const std::vector<base::FilePath>& paths,
-    stats::FileCleanupReason reason) {
-  base::ThreadRestrictions::AssertIOAllowed();
-  int num_delete_attempted = 0;
-  int num_delete_failed = 0;
-  int num_delete_by_external = 0;
-  for (const base::FilePath& path : paths) {
-    if (!base::PathExists(path)) {
-      num_delete_by_external++;
-      continue;
-    }
-
-    num_delete_attempted++;
-    DCHECK(!base::DirectoryExists(path));
-
-    if (!base::DeleteFile(path, false /* recursive */)) {
-      num_delete_failed++;
-    }
-  }
-
-  stats::LogFileCleanupStatus(reason, num_delete_attempted, num_delete_failed,
-                              num_delete_by_external);
+void FileMonitorImpl::HardRecover(const InitCallback& callback) {
+  base::PostTaskAndReplyWithResult(
+      file_thread_task_runner_.get(), FROM_HERE,
+      base::Bind(&HardRecoverOnFileThread, download_file_dir_), callback);
 }
 
 bool FileMonitorImpl::ReadyForCleanup(const Entry* entry) {
diff --git a/components/download/internal/file_monitor_impl.h b/components/download/internal/file_monitor_impl.h
index 2baa359..6d2e615 100644
--- a/components/download/internal/file_monitor_impl.h
+++ b/components/download/internal/file_monitor_impl.h
@@ -34,20 +34,18 @@
       base::TimeDelta file_keep_alive_time);
   ~FileMonitorImpl() override;
 
+  // FileMonitor implementation.
   void Initialize(const InitCallback& callback) override;
   void DeleteUnknownFiles(
       const Model::EntryList& known_entries,
       const std::vector<DriverEntry>& known_driver_entries) override;
   std::vector<Entry*> CleanupFilesForCompletedEntries(
       const Model::EntryList& entries) override;
-  void DeleteFiles(const std::vector<base::FilePath>& files_to_remove,
+  void DeleteFiles(const std::set<base::FilePath>& files_to_remove,
                    stats::FileCleanupReason reason) override;
+  void HardRecover(const InitCallback& callback) override;
 
  private:
-  void DeleteUnknownFilesOnFileThread(
-      const std::set<base::FilePath>& paths_in_db);
-  void DeleteFilesOnFileThread(const std::vector<base::FilePath>& paths,
-                               stats::FileCleanupReason reason);
   bool ReadyForCleanup(const Entry* entry);
 
   const base::FilePath download_file_dir_;
diff --git a/components/download/internal/file_monitor_unittest.cc b/components/download/internal/file_monitor_unittest.cc
index b7443df6..a1a78151 100644
--- a/components/download/internal/file_monitor_unittest.cc
+++ b/components/download/internal/file_monitor_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/files/scoped_temp_dir.h"
 #include "base/guid.h"
 #include "base/memory/ptr_util.h"
+#include "base/optional.h"
 #include "base/test/test_simple_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/download/internal/driver_entry.h"
@@ -35,6 +36,8 @@
   }
   ~FileMonitorTest() override = default;
 
+  void HardRecoveryResponse(bool result);
+
  protected:
   base::FilePath CreateTemporaryFile(std::string file_name);
 
@@ -44,6 +47,8 @@
   base::FilePath download_dir_;
   std::unique_ptr<FileMonitor> monitor_;
 
+  base::Optional<bool> hard_recovery_result_;
+
  private:
   DISALLOW_COPY_AND_ASSIGN(FileMonitorTest);
 };
@@ -57,6 +62,10 @@
   return file_path;
 }
 
+void FileMonitorTest::HardRecoveryResponse(bool result) {
+  hard_recovery_result_ = result;
+}
+
 TEST_F(FileMonitorTest, TestDeleteUnknownFiles) {
   Entry entry1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
   entry1.target_file_path = CreateTemporaryFile(entry1.guid);
@@ -135,4 +144,23 @@
   EXPECT_TRUE(base::PathExists(entry2.target_file_path));
 }
 
+TEST_F(FileMonitorTest, TestHardRecovery) {
+  base::FilePath temp_file1 = CreateTemporaryFile("temp1");
+  base::FilePath temp_file2 = CreateTemporaryFile("temp2");
+
+  auto callback = base::Bind(&FileMonitorTest::HardRecoveryResponse,
+                             base::Unretained(this));
+
+  EXPECT_TRUE(base::PathExists(temp_file1));
+  EXPECT_TRUE(base::PathExists(temp_file2));
+
+  monitor_->HardRecover(callback);
+  task_runner_->RunUntilIdle();
+
+  EXPECT_TRUE(hard_recovery_result_.has_value());
+  EXPECT_TRUE(hard_recovery_result_.value());
+  EXPECT_FALSE(base::PathExists(temp_file1));
+  EXPECT_FALSE(base::PathExists(temp_file2));
+}
+
 }  // namespace download
diff --git a/components/download/internal/stats.h b/components/download/internal/stats.h
index 521fa5a..332b2936 100644
--- a/components/download/internal/stats.h
+++ b/components/download/internal/stats.h
@@ -93,6 +93,8 @@
   // it will be used only internally by the Stats class.
   EXTERNAL = 3,
 
+  // We're trying to remove all files as part of a hard recovery attempt.
+  HARD_RECOVERY = 4,
 };
 
 // Logs the results of starting up the Controller.  Will log each failure reason
diff --git a/components/download/internal/test/empty_client.cc b/components/download/internal/test/empty_client.cc
index 5318bc5..7f14c37 100644
--- a/components/download/internal/test/empty_client.cc
+++ b/components/download/internal/test/empty_client.cc
@@ -10,6 +10,8 @@
 void EmptyClient::OnServiceInitialized(
     const std::vector<std::string>& outstanding_download_guids) {}
 
+void EmptyClient::OnServiceUnavailable() {}
+
 Client::ShouldDownload EmptyClient::OnDownloadStarted(
     const std::string& guid,
     const std::vector<GURL>& url_chain,
diff --git a/components/download/internal/test/empty_client.h b/components/download/internal/test/empty_client.h
index cbfdf2a..64fcc6a 100644
--- a/components/download/internal/test/empty_client.h
+++ b/components/download/internal/test/empty_client.h
@@ -19,6 +19,7 @@
   // Client implementation.
   void OnServiceInitialized(
       const std::vector<std::string>& outstanding_download_guids) override;
+  void OnServiceUnavailable() override;
   ShouldDownload OnDownloadStarted(
       const std::string& guid,
       const std::vector<GURL>& url_chain,
diff --git a/components/download/internal/test/mock_client.h b/components/download/internal/test/mock_client.h
index f4b255b..ae8f21c 100644
--- a/components/download/internal/test/mock_client.h
+++ b/components/download/internal/test/mock_client.h
@@ -19,6 +19,7 @@
 
   // Client implementation.
   MOCK_METHOD1(OnServiceInitialized, void(const std::vector<std::string>&));
+  MOCK_METHOD0(OnServiceUnavailable, void());
   MOCK_METHOD3(
       OnDownloadStarted,
       ShouldDownload(const std::string&,
diff --git a/components/download/public/client.h b/components/download/public/client.h
index 6f65610..ad5de8a 100644
--- a/components/download/public/client.h
+++ b/components/download/public/client.h
@@ -59,6 +59,9 @@
   virtual void OnServiceInitialized(
       const std::vector<std::string>& outstanding_download_guids) = 0;
 
+  // Called when the DownloadService fails to initialize and should not be used.
+  virtual void OnServiceUnavailable() = 0;
+
   // Return whether or not the download should be aborted (potentially in
   // response to |headers|).  The download will be downloading at the time this
   // call is made.
diff --git a/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider_unittest.cc b/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider_unittest.cc
index 7d8489c..c43ad141 100644
--- a/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider_unittest.cc
+++ b/components/ntp_snippets/offline_pages/recent_tab_suggestions_provider_unittest.cc
@@ -116,7 +116,9 @@
     int tab_id = offline_pages::RecentTabsUIAdapterDelegate::TabIdFromClientId(
         item.client_id);
     RemoveTab(tab_id);
-    ui_adapter_->OfflinePageDeleted(item.offline_id, item.client_id);
+    ui_adapter_->OfflinePageDeleted(
+        offline_pages::OfflinePageModel::DeletedPageInfo(
+            item.offline_id, item.client_id, "" /* request_origin */));
   }
 
   std::set<std::string> ReadDismissedIDsFromPrefs() {
diff --git a/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc b/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc
index df17693..a595715 100644
--- a/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc
+++ b/components/ntp_snippets/remote/prefetched_pages_tracker_impl.cc
@@ -86,10 +86,9 @@
 }
 
 void PrefetchedPagesTrackerImpl::OfflinePageDeleted(
-    int64_t offline_id,
-    const offline_pages::ClientId& client_id) {
+    const offline_pages::OfflinePageModel::DeletedPageInfo& page_info) {
   std::map<int64_t, GURL>::iterator it =
-      offline_id_to_url_mapping_.find(offline_id);
+      offline_id_to_url_mapping_.find(page_info.offline_id);
   if (it != offline_id_to_url_mapping_.end()) {
     DCHECK(prefetched_urls_.count(it->second));
     prefetched_urls_.erase(it->second);
diff --git a/components/ntp_snippets/remote/prefetched_pages_tracker_impl.h b/components/ntp_snippets/remote/prefetched_pages_tracker_impl.h
index 045c98e..32be1db1 100644
--- a/components/ntp_snippets/remote/prefetched_pages_tracker_impl.h
+++ b/components/ntp_snippets/remote/prefetched_pages_tracker_impl.h
@@ -41,8 +41,9 @@
   void OfflinePageAdded(
       offline_pages::OfflinePageModel* model,
       const offline_pages::OfflinePageItem& added_page) override;
-  void OfflinePageDeleted(int64_t offline_id,
-                          const offline_pages::ClientId& client_id) override;
+  void OfflinePageDeleted(
+      const offline_pages::OfflinePageModel::DeletedPageInfo& page_info)
+      override;
 
  private:
   void Initialize(const std::vector<offline_pages::OfflinePageItem>&
diff --git a/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc b/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc
index 15d22c013..ddbb295 100644
--- a/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc
+++ b/components/ntp_snippets/remote/prefetched_pages_tracker_impl_unittest.cc
@@ -141,7 +141,8 @@
 
   ASSERT_TRUE(
       tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
-  tracker.OfflinePageDeleted(item.offline_id, item.client_id);
+  tracker.OfflinePageDeleted(offline_pages::OfflinePageModel::DeletedPageInfo(
+      item.offline_id, item.client_id, "" /* request_origin */));
   EXPECT_FALSE(
       tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
 }
@@ -160,8 +161,9 @@
 
   ASSERT_TRUE(
       tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
-  tracker.OfflinePageDeleted(manually_downloaded_item.offline_id,
-                             manually_downloaded_item.client_id);
+  tracker.OfflinePageDeleted(offline_pages::OfflinePageModel::DeletedPageInfo(
+      manually_downloaded_item.offline_id, manually_downloaded_item.client_id,
+      "" /* request_origin */));
   EXPECT_TRUE(
       tracker.PrefetchedOfflinePageExists(GURL("http://prefetched.com")));
 }
diff --git a/components/offline_pages/core/downloads/download_ui_adapter.cc b/components/offline_pages/core/downloads/download_ui_adapter.cc
index 7e1368ec..310531ad 100644
--- a/components/offline_pages/core/downloads/download_ui_adapter.cc
+++ b/components/offline_pages/core/downloads/download_ui_adapter.cc
@@ -116,11 +116,11 @@
   AddItemHelper(base::MakeUnique<ItemInfo>(added_page, temporarily_hidden));
 }
 
-void DownloadUIAdapter::OfflinePageDeleted(int64_t offline_id,
-                                           const ClientId& client_id) {
-  if (!delegate_->IsVisibleInUI(client_id))
+void DownloadUIAdapter::OfflinePageDeleted(
+    const OfflinePageModel::DeletedPageInfo& page_info) {
+  if (!delegate_->IsVisibleInUI(page_info.client_id))
     return;
-  DeleteItemHelper(client_id.id);
+  DeleteItemHelper(page_info.client_id.id);
 }
 
 // RequestCoordinator::Observer
diff --git a/components/offline_pages/core/downloads/download_ui_adapter.h b/components/offline_pages/core/downloads/download_ui_adapter.h
index 9868fb0..ec1f8d56 100644
--- a/components/offline_pages/core/downloads/download_ui_adapter.h
+++ b/components/offline_pages/core/downloads/download_ui_adapter.h
@@ -109,8 +109,8 @@
   void OfflinePageModelLoaded(OfflinePageModel* model) override;
   void OfflinePageAdded(OfflinePageModel* model,
                         const OfflinePageItem& added_page) override;
-  void OfflinePageDeleted(int64_t offline_id,
-                          const ClientId& client_id) override;
+  void OfflinePageDeleted(
+      const OfflinePageModel::DeletedPageInfo& page_info) override;
 
   // RequestCoordinator::Observer
   void OnAdded(const SavePageRequest& request) override;
diff --git a/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc b/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc
index 60cafb4..b5c2b32 100644
--- a/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc
+++ b/components/offline_pages/core/downloads/download_ui_adapter_unittest.cc
@@ -112,8 +112,9 @@
   void DeletePageAndNotifyAdapter(const std::string& guid) {
     for (const auto& page : pages) {
       if (page.second.client_id.id == guid) {
-        observer_->OfflinePageDeleted(page.second.offline_id,
-                                      page.second.client_id);
+        DeletedPageInfo info(page.second.offline_id, page.second.client_id,
+                             page.second.request_origin);
+        observer_->OfflinePageDeleted(info);
         pages.erase(page.first);
         return;
       }
diff --git a/components/offline_pages/core/offline_page_model.cc b/components/offline_pages/core/offline_page_model.cc
index e0d7cbff4..109cec6f 100644
--- a/components/offline_pages/core/offline_page_model.cc
+++ b/components/offline_pages/core/offline_page_model.cc
@@ -25,6 +25,14 @@
 
 OfflinePageModel::SavePageParams::~SavePageParams() {}
 
+OfflinePageModel::DeletedPageInfo::DeletedPageInfo(
+    int64_t offline_id,
+    const ClientId& client_id,
+    const std::string& request_origin)
+    : offline_id(offline_id),
+      client_id(client_id),
+      request_origin(request_origin) {}
+
 // static
 bool OfflinePageModel::CanSaveURL(const GURL& url) {
   return url.is_valid() && url.SchemeIsHTTPOrHTTPS();
diff --git a/components/offline_pages/core/offline_page_model.h b/components/offline_pages/core/offline_page_model.h
index a155222..3f10618 100644
--- a/components/offline_pages/core/offline_page_model.h
+++ b/components/offline_pages/core/offline_page_model.h
@@ -82,6 +82,19 @@
     std::string request_origin;
   };
 
+  // Information about a deleted page.
+  struct DeletedPageInfo {
+    DeletedPageInfo(int64_t offline_id,
+                    const ClientId& client_id,
+                    const std::string& request_origin);
+    // The ID of the deleted page.
+    int64_t offline_id;
+    // Client ID of the deleted page.
+    ClientId client_id;
+    // The origin that the page was saved on behalf of.
+    std::string request_origin;
+  };
+
   // Observer of the OfflinePageModel.
   class Observer {
    public:
@@ -93,8 +106,7 @@
                                   const OfflinePageItem& added_page) = 0;
 
     // Invoked when an offline copy related to |offline_id| was deleted.
-    virtual void OfflinePageDeleted(int64_t offline_id,
-                                    const ClientId& client_id) = 0;
+    virtual void OfflinePageDeleted(const DeletedPageInfo& page_info) = 0;
 
    protected:
     virtual ~Observer() = default;
diff --git a/components/offline_pages/core/offline_page_model_impl.cc b/components/offline_pages/core/offline_page_model_impl.cc
index a850fe3..4909a12c 100644
--- a/components/offline_pages/core/offline_page_model_impl.cc
+++ b/components/offline_pages/core/offline_page_model_impl.cc
@@ -982,8 +982,9 @@
   }
 
   for (const auto& page : result->updated_items) {
+    DeletedPageInfo info(page.offline_id, page.client_id, page.request_origin);
     for (Observer& observer : observers_)
-      observer.OfflinePageDeleted(page.offline_id, page.client_id);
+      observer.OfflinePageDeleted(info);
   }
 
   DeletePageResult delete_result;
diff --git a/components/offline_pages/core/offline_page_model_impl_unittest.cc b/components/offline_pages/core/offline_page_model_impl_unittest.cc
index 609bb33d..235dbe5f 100644
--- a/components/offline_pages/core/offline_page_model_impl_unittest.cc
+++ b/components/offline_pages/core/offline_page_model_impl_unittest.cc
@@ -56,6 +56,7 @@
 const ClientId kTestUserRequestedClientId(kUserRequestedNamespace, "714");
 const int64_t kTestFileSize = 876543LL;
 const base::string16 kTestTitle = base::UTF8ToUTF16("a title");
+const std::string kRequestOrigin("abc.xyz");
 
 bool URLSpecContains(std::string contains_value, const GURL& url) {
   std::string spec = url.spec();
@@ -80,8 +81,8 @@
   void OfflinePageModelLoaded(OfflinePageModel* model) override;
   void OfflinePageAdded(OfflinePageModel* model,
                         const OfflinePageItem& added_page) override;
-  void OfflinePageDeleted(int64_t offline_id,
-                          const ClientId& client_id) override;
+  void OfflinePageDeleted(
+      const OfflinePageModel::DeletedPageInfo& pageInfo) override;
 
   // OfflinePageTestArchiver::Observer implementation.
   void SetLastPathCreatedByArchiver(const base::FilePath& file_path) override;
@@ -136,11 +137,11 @@
       std::unique_ptr<OfflinePageArchiver> archiver);
 
   // Saves the page without waiting for it to finish.
-  void SavePageWithArchiverAsync(
-      const GURL& url,
-      const ClientId& client_id,
-      const GURL& original_url,
-      std::unique_ptr<OfflinePageArchiver> archiver);
+  void SavePageWithArchiverAsync(const GURL& url,
+                                 const ClientId& client_id,
+                                 const GURL& original_url,
+                                 const std::string& request_origin,
+                                 std::unique_ptr<OfflinePageArchiver> archiver);
 
   // All 3 methods below will wait for the save to finish.
   void SavePageWithArchiver(
@@ -153,6 +154,10 @@
   // Returns the offline ID of the saved page.
   std::pair<SavePageResult, int64_t> SavePage(const GURL& url,
                                               const ClientId& client_id);
+  std::pair<SavePageResult, int64_t> SavePage(
+      const GURL& url,
+      const ClientId& client_id,
+      const std::string& request_origin);
 
   void DeletePage(int64_t offline_id, const DeletePageCallback& callback) {
     std::vector<int64_t> offline_ids;
@@ -183,6 +188,10 @@
 
   ClientId last_deleted_client_id() const { return last_deleted_client_id_; }
 
+  std::string last_deleted_request_origin() const {
+    return last_deleted_request_origin_;
+  }
+
   const base::FilePath& last_archiver_path() { return last_archiver_path_; }
 
   int last_cleared_pages_count() const { return last_cleared_pages_count_; }
@@ -207,6 +216,7 @@
   base::FilePath last_archiver_path_;
   int64_t last_deleted_offline_id_;
   ClientId last_deleted_client_id_;
+  std::string last_deleted_request_origin_;
   CheckPagesExistOfflineResult last_pages_exist_result_;
   int last_cleared_pages_count_;
   DeletePageResult last_clear_page_result_;
@@ -250,10 +260,11 @@
   ASSERT_EQ(model_.get(), model);
 }
 
-void OfflinePageModelImplTest::OfflinePageDeleted(int64_t offline_id,
-                                                  const ClientId& client_id) {
-  last_deleted_offline_id_ = offline_id;
-  last_deleted_client_id_ = client_id;
+void OfflinePageModelImplTest::OfflinePageDeleted(
+    const OfflinePageModel::DeletedPageInfo& info) {
+  last_deleted_offline_id_ = info.offline_id;
+  last_deleted_client_id_ = info.client_id;
+  last_deleted_request_origin_ = info.request_origin;
 }
 
 void OfflinePageModelImplTest::OfflinePageAdded(
@@ -354,12 +365,14 @@
     const GURL& url,
     const ClientId& client_id,
     const GURL& original_url,
+    const std::string& request_origin,
     std::unique_ptr<OfflinePageArchiver> archiver) {
   OfflinePageModel::SavePageParams save_page_params;
   save_page_params.url = url;
   save_page_params.client_id = client_id;
   save_page_params.original_url = original_url;
   save_page_params.is_background = false;
+  save_page_params.request_origin = request_origin;
   SavePageWithParamsAsync(save_page_params, std::move(archiver));
 }
 
@@ -367,7 +380,7 @@
     const GURL& url,
     const ClientId& client_id,
     std::unique_ptr<OfflinePageArchiver> archiver) {
-  SavePageWithArchiverAsync(url, client_id, GURL(), std::move(archiver));
+  SavePageWithArchiverAsync(url, client_id, GURL(), "", std::move(archiver));
   PumpLoop();
 }
 
@@ -376,15 +389,23 @@
     const ClientId& client_id,
     OfflinePageArchiver::ArchiverResult result) {
   std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver(url, result));
-  SavePageWithArchiverAsync(url, client_id, GURL(), std::move(archiver));
+  SavePageWithArchiverAsync(url, client_id, GURL(), "", std::move(archiver));
   PumpLoop();
 }
 
 std::pair<SavePageResult, int64_t>
 OfflinePageModelImplTest::SavePage(const GURL& url, const ClientId& client_id) {
+  return SavePage(url, client_id, "");
+}
+
+std::pair<SavePageResult, int64_t> OfflinePageModelImplTest::SavePage(
+    const GURL& url,
+    const ClientId& client_id,
+    const std::string& request_origin) {
   std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver(
       url, OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED));
-  SavePageWithArchiverAsync(url, client_id, GURL(), std::move(archiver));
+  SavePageWithArchiverAsync(url, client_id, GURL(), request_origin,
+                            std::move(archiver));
   PumpLoop();
   return std::make_pair(last_save_result_, last_save_offline_id_);
 }
@@ -514,8 +535,8 @@
 
   std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver(
       kTestUrl, OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED));
-  SavePageWithArchiverAsync(
-      kTestUrl, kTestClientId1, kTestUrl2, std::move(archiver));
+  SavePageWithArchiverAsync(kTestUrl, kTestClientId1, kTestUrl2, "",
+                            std::move(archiver));
   PumpLoop();
   EXPECT_TRUE(HasPages(kTestClientNamespace));
 
@@ -543,6 +564,44 @@
   EXPECT_EQ(0, offline_pages[0].flags);
   EXPECT_EQ(kTestTitle, offline_pages[0].title);
   EXPECT_EQ(kTestUrl2, offline_pages[0].original_url);
+  EXPECT_EQ("", offline_pages[0].request_origin);
+}
+
+TEST_F(OfflinePageModelImplTest, SavePageSuccessfulWithRequestOrigin) {
+  EXPECT_FALSE(HasPages(kTestClientNamespace));
+
+  std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver(
+      kTestUrl, OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED));
+  SavePageWithArchiverAsync(kTestUrl, kTestClientId1, kTestUrl2, kRequestOrigin,
+                            std::move(archiver));
+  PumpLoop();
+  EXPECT_TRUE(HasPages(kTestClientNamespace));
+
+  OfflinePageTestStore* store = GetStore();
+  EXPECT_EQ(kTestUrl, store->last_saved_page().url);
+  EXPECT_EQ(kTestClientId1.id, store->last_saved_page().client_id.id);
+  EXPECT_EQ(kTestClientId1.name_space,
+            store->last_saved_page().client_id.name_space);
+  // Save last_archiver_path since it will be referred to later.
+  base::FilePath archiver_path = last_archiver_path();
+  EXPECT_EQ(archiver_path, store->last_saved_page().file_path);
+  EXPECT_EQ(kTestFileSize, store->last_saved_page().file_size);
+  EXPECT_EQ(SavePageResult::SUCCESS, last_save_result());
+  ResetResults();
+
+  const std::vector<OfflinePageItem>& offline_pages = GetAllPages();
+
+  ASSERT_EQ(1UL, offline_pages.size());
+  EXPECT_EQ(kTestUrl, offline_pages[0].url);
+  EXPECT_EQ(kTestClientId1.id, offline_pages[0].client_id.id);
+  EXPECT_EQ(kTestClientId1.name_space, offline_pages[0].client_id.name_space);
+  EXPECT_EQ(archiver_path, offline_pages[0].file_path);
+  EXPECT_EQ(kTestFileSize, offline_pages[0].file_size);
+  EXPECT_EQ(0, offline_pages[0].access_count);
+  EXPECT_EQ(0, offline_pages[0].flags);
+  EXPECT_EQ(kTestTitle, offline_pages[0].title);
+  EXPECT_EQ(kTestUrl2, offline_pages[0].original_url);
+  EXPECT_EQ(kRequestOrigin, offline_pages[0].request_origin);
 }
 
 TEST_F(OfflinePageModelImplTest, SavePageOfflineArchiverCancelled) {
@@ -605,14 +664,15 @@
   // CompleteCreateArchive() is called.
   OfflinePageTestArchiver* archiver_ptr = archiver.get();
   archiver_ptr->set_delayed(true);
-  SavePageWithArchiverAsync(
-      kTestUrl, kTestClientId1, GURL(), std::move(archiver));
+  // First page has no request origin.
+  SavePageWithArchiverAsync(kTestUrl, kTestClientId1, GURL(), "",
+                            std::move(archiver));
   EXPECT_TRUE(archiver_ptr->create_archive_called());
   // |remove_popup_overlay| should not be turned on on foreground mode.
   EXPECT_FALSE(archiver_ptr->create_archive_params().remove_popup_overlay);
 
-  // Request to save another page.
-  SavePage(kTestUrl2, kTestClientId2);
+  // Request to save another page, with request origin.
+  SavePage(kTestUrl2, kTestClientId2, kRequestOrigin);
 
   OfflinePageTestStore* store = GetStore();
 
@@ -621,6 +681,7 @@
   base::FilePath archiver_path2 = last_archiver_path();
   EXPECT_EQ(archiver_path2, store->last_saved_page().file_path);
   EXPECT_EQ(kTestFileSize, store->last_saved_page().file_size);
+  EXPECT_EQ(kRequestOrigin, store->last_saved_page().request_origin);
   EXPECT_EQ(SavePageResult::SUCCESS, last_save_result());
 
   ResetResults();
@@ -634,6 +695,7 @@
   base::FilePath archiver_path = last_archiver_path();
   EXPECT_EQ(archiver_path, store->last_saved_page().file_path);
   EXPECT_EQ(kTestFileSize, store->last_saved_page().file_size);
+  EXPECT_EQ("", store->last_saved_page().request_origin);
   EXPECT_EQ(SavePageResult::SUCCESS, last_save_result());
 
   ResetResults();
@@ -659,12 +721,14 @@
   EXPECT_EQ(kTestFileSize, page1->file_size);
   EXPECT_EQ(0, page1->access_count);
   EXPECT_EQ(0, page1->flags);
+  EXPECT_EQ("", page1->request_origin);
   EXPECT_EQ(kTestUrl2, page2->url);
   EXPECT_EQ(kTestClientId2, page2->client_id);
   EXPECT_EQ(archiver_path2, page2->file_path);
   EXPECT_EQ(kTestFileSize, page2->file_size);
   EXPECT_EQ(0, page2->access_count);
   EXPECT_EQ(0, page2->flags);
+  EXPECT_EQ(kRequestOrigin, page2->request_origin);
 }
 
 TEST_F(OfflinePageModelImplTest, SavePageOnBackground) {
@@ -711,15 +775,15 @@
 TEST_F(OfflinePageModelImplTest, DeletePageSuccessful) {
   OfflinePageTestStore* store = GetStore();
 
-  // Save one page.
-  SavePage(kTestUrl, kTestClientId1);
+  // Save one page with request origin.
+  SavePage(kTestUrl, kTestClientId1, kRequestOrigin);
   int64_t offline1 = last_save_offline_id();
   EXPECT_EQ(SavePageResult::SUCCESS, last_save_result());
   EXPECT_EQ(1u, store->GetAllPages().size());
 
   ResetResults();
 
-  // Save another page.
+  // Save another page, no request origin.
   SavePage(kTestUrl2, kTestClientId2);
   int64_t offline2 = last_save_offline_id();
   EXPECT_EQ(SavePageResult::SUCCESS, last_save_result());
@@ -735,6 +799,7 @@
 
   EXPECT_EQ(last_deleted_offline_id(), offline1);
   EXPECT_EQ(last_deleted_client_id(), kTestClientId1);
+  EXPECT_EQ(last_deleted_request_origin(), kRequestOrigin);
   EXPECT_EQ(DeletePageResult::SUCCESS, last_delete_result());
   ASSERT_EQ(1u, store->GetAllPages().size());
   EXPECT_EQ(kTestUrl2, store->GetAllPages()[0].url);
@@ -749,6 +814,7 @@
 
   EXPECT_EQ(last_deleted_offline_id(), offline2);
   EXPECT_EQ(last_deleted_client_id(), kTestClientId2);
+  EXPECT_EQ(last_deleted_request_origin(), "");
   EXPECT_EQ(DeletePageResult::SUCCESS, last_delete_result());
   EXPECT_EQ(0u, store->GetAllPages().size());
 }
@@ -1023,8 +1089,8 @@
 TEST_F(OfflinePageModelImplTest, GetPagesByAllURLS) {
   std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver(
       kTestUrl, OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED));
-  SavePageWithArchiverAsync(
-      kTestUrl, kTestClientId1, kTestUrl2, std::move(archiver));
+  SavePageWithArchiverAsync(kTestUrl, kTestClientId1, kTestUrl2, "",
+                            std::move(archiver));
   PumpLoop();
 
   SavePage(kTestUrl2, kTestClientId2);
@@ -1277,7 +1343,7 @@
 TEST_F(OfflinePageModelImplTest, GetPagesMatchingQuery) {
   std::unique_ptr<OfflinePageTestArchiver> archiver(BuildArchiver(
       kTestUrl, OfflinePageArchiver::ArchiverResult::SUCCESSFULLY_CREATED));
-  SavePageWithArchiverAsync(kTestUrl, kTestClientId1, kTestUrl2,
+  SavePageWithArchiverAsync(kTestUrl, kTestClientId1, kTestUrl2, "",
                             std::move(archiver));
   PumpLoop();
 
diff --git a/components/omnibox/browser/history_quick_provider.cc b/components/omnibox/browser/history_quick_provider.cc
index 2768387e..c37f4819 100644
--- a/components/omnibox/browser/history_quick_provider.cc
+++ b/components/omnibox/browser/history_quick_provider.cc
@@ -196,40 +196,29 @@
   match.typed_count = info.typed_count();
   match.destination_url = info.url();
   DCHECK(match.destination_url.is_valid());
+
+  // The inline_autocomplete_offset should be adjusted based on the formatting
+  // applied to |fill_into_edit|.
   size_t inline_autocomplete_offset = URLPrefix::GetInlineAutocompleteOffset(
       autocomplete_input_.text(), FixupUserInput(autocomplete_input_).second,
       false, base::UTF8ToUTF16(info.url().spec()));
-
-  base::OffsetAdjuster::Adjustments adjustments;
-  auto format_types =
-      AutocompleteMatch::GetFormatTypes(!history_match.match_in_scheme);
-  match.contents = url_formatter::FormatUrlWithAdjustments(
-      info.url(), format_types, net::UnescapeRule::SPACES, nullptr, nullptr,
-      &adjustments);
+  auto fill_into_edit_format_types = url_formatter::kFormatUrlOmitAll;
+  if (history_match.match_in_scheme)
+    fill_into_edit_format_types &= ~url_formatter::kFormatUrlOmitHTTP;
   match.fill_into_edit =
       AutocompleteInput::FormattedStringWithEquivalentMeaning(
-          info.url(), match.contents, client()->GetSchemeClassifier());
-  std::vector<size_t> offsets =
-      OffsetsFromTermMatches(history_match.url_matches);
-  // In addition to knowing how |offsets| is transformed, we need to know how
-  // |inline_autocomplete_offset| is transformed.  We add it to the end of
-  // |offsets|, compute how everything is transformed, then remove it from the
-  // end.
-  offsets.push_back(inline_autocomplete_offset);
-  base::OffsetAdjuster::AdjustOffsets(adjustments, &offsets);
-  inline_autocomplete_offset = offsets.back();
-  offsets.pop_back();
-  TermMatches new_matches =
-      ReplaceOffsetsInTermMatches(history_match.url_matches, offsets);
-  match.contents_class =
-      SpansFromTermMatch(new_matches, match.contents.length(), true);
+          info.url(),
+          url_formatter::FormatUrl(info.url(), fill_into_edit_format_types,
+                                   net::UnescapeRule::SPACES, nullptr, nullptr,
+                                   &inline_autocomplete_offset),
+          client()->GetSchemeClassifier());
 
   // Set |inline_autocompletion| and |allowed_to_be_default_match| if possible.
   if (inline_autocomplete_offset != base::string16::npos) {
     // |inline_autocomplete_offset| may be beyond the end of the
     // |match.fill_into_edit| if the user has typed an URL with a scheme and the
     // last character typed is a slash.  That slash is removed by the
-    // FormatURLWithAdjustments call above.
+    // FormatUrlWithOffsets call above.
     if (inline_autocomplete_offset < match.fill_into_edit.length()) {
       match.inline_autocompletion =
           match.fill_into_edit.substr(inline_autocomplete_offset);
@@ -240,6 +229,20 @@
   match.EnsureUWYTIsAllowedToBeDefault(autocomplete_input_,
                                        client()->GetTemplateURLService());
 
+  // The term match offsets should be adjusted based on the formatting
+  // applied to the suggestion contents displayed in the dropdown.
+  std::vector<size_t> offsets =
+      OffsetsFromTermMatches(history_match.url_matches);
+  match.contents = url_formatter::FormatUrlWithOffsets(
+      info.url(),
+      AutocompleteMatch::GetFormatTypes(!history_match.match_in_scheme),
+      net::UnescapeRule::SPACES, nullptr, nullptr, &offsets);
+
+  TermMatches new_matches =
+      ReplaceOffsetsInTermMatches(history_match.url_matches, offsets);
+  match.contents_class =
+      SpansFromTermMatch(new_matches, match.contents.length(), true);
+
   // Format the description autocomplete presentation.
   match.description = info.title();
   match.description_class = SpansFromTermMatch(
diff --git a/components/payments_strings.grdp b/components/payments_strings.grdp
index e5c7902..716de10 100644
--- a/components/payments_strings.grdp
+++ b/components/payments_strings.grdp
@@ -381,6 +381,9 @@
   <message name="IDS_PAYMENTS_ROW_ACCESSIBLE_NAME_FORMAT" desc="The format to build the screen reader string for Payment Sheet rows">
     <ph name="ROW_NAME">$1<ex>Payment Method</ex></ph> <ph name="ROW_CONTENT">$2<ex>VISA ****1234</ex></ph>
   </message>
+  <message name="IDS_PAYMENTS_ROW_ACCESSIBLE_NAME_SELECTED_FORMAT" desc="The format to build the screen reader string for Payment Sheet rows, with an added indication that this row has been selected">
+    <ph name="ROW_NAME">$1<ex>Payment Method</ex></ph>, currently selected. <ph name="ROW_CONTENT">$2<ex>VISA ****1234</ex></ph>
+  </message>
   <message name="IDS_PAYMENTS_PROFILE_LABELS_ACCESSIBLE_FORMAT" desc="The format to build the screen reader string for profile labels">
     <ph name="FIRST_LABEL">$1<ex>VISA ****1234</ex></ph> <ph name="SECOND_LABEL">$2<ex>Homer Simpson</ex></ph> <ph name="THIRD_LABEL">$3<ex>123 Fake Street</ex></ph>
   </message>
diff --git a/components/proximity_auth/switches.cc b/components/proximity_auth/switches.cc
index 69f739a..44f6b3d 100644
--- a/components/proximity_auth/switches.cc
+++ b/components/proximity_auth/switches.cc
@@ -19,13 +19,6 @@
 // 20) without password entry.
 const char kEnableForcePasswordReauth[] = "force-password-reauth";
 
-// Enables close proximity detection. This allows the user to set a setting to
-// require very close proximity between the remote device and the local device
-// in order to unlock the local device, which trades off convenience for
-// security.
-const char kEnableProximityDetection[] =
-    "enable-proximity-auth-proximity-detection";
-
 // Force easy unlock app loading in test.
 // TODO(xiyuan): Remove this when app could be bundled with Chrome.
 const char kForceLoadEasyUnlockAppInTests[] =
diff --git a/components/proximity_auth/switches.h b/components/proximity_auth/switches.h
index 60c9264..0ec6d182 100644
--- a/components/proximity_auth/switches.h
+++ b/components/proximity_auth/switches.h
@@ -11,7 +11,6 @@
 extern const char kEnableBluetoothLowEnergyDiscovery[];
 extern const char kEnableChromeOSLogin[];
 extern const char kEnableForcePasswordReauth[];
-extern const char kEnableProximityDetection[];
 extern const char kForceLoadEasyUnlockAppInTests[];
 
 }  // namespace switches
diff --git a/components/sessions/content/content_serialized_navigation_builder.cc b/components/sessions/content/content_serialized_navigation_builder.cc
index 7acfa8b..94f20a0 100644
--- a/components/sessions/content/content_serialized_navigation_builder.cc
+++ b/components/sessions/content/content_serialized_navigation_builder.cc
@@ -22,7 +22,8 @@
 SerializedNavigationEntry
 ContentSerializedNavigationBuilder::FromNavigationEntry(
     int index,
-    const content::NavigationEntry& entry) {
+    const content::NavigationEntry& entry,
+    SerializationOptions serialization_options) {
   SerializedNavigationEntry navigation;
   navigation.index_ = index;
   navigation.unique_id_ = entry.GetUniqueID();
@@ -30,7 +31,8 @@
   navigation.referrer_policy_ = entry.GetReferrer().policy;
   navigation.virtual_url_ = entry.GetVirtualURL();
   navigation.title_ = entry.GetTitle();
-  navigation.encoded_page_state_ = entry.GetPageState().ToEncodedData();
+  if (!(serialization_options & SerializationOptions::EXCLUDE_PAGE_STATE))
+    navigation.encoded_page_state_ = entry.GetPageState().ToEncodedData();
   navigation.transition_type_ = entry.GetTransitionType();
   navigation.has_post_data_ = entry.GetHasPostData();
   navigation.post_id_ = entry.GetPostID();
diff --git a/components/sessions/content/content_serialized_navigation_builder.h b/components/sessions/content/content_serialized_navigation_builder.h
index b8cd76d..ebb9afb0 100644
--- a/components/sessions/content/content_serialized_navigation_builder.h
+++ b/components/sessions/content/content_serialized_navigation_builder.h
@@ -22,11 +22,25 @@
 // classes.
 class SESSIONS_EXPORT ContentSerializedNavigationBuilder {
  public:
+  // Set of options for serializing a navigation. Multiple options can be
+  // combined by bit masking.
+  enum SerializationOptions {
+    // Serialized all available navigation data.
+    DEFAULT = 0x0,
+
+    // Exclude page state data. Serializing page state data can involve heavy
+    // processing on pages with deep iframe trees, so should be avoided if not
+    // necessary.
+    EXCLUDE_PAGE_STATE = 0x1,
+  };
+
   // Construct a SerializedNavigationEntry for a particular index from the given
   // NavigationEntry.
   static SerializedNavigationEntry FromNavigationEntry(
       int index,
-      const content::NavigationEntry& entry);
+      const content::NavigationEntry& entry,
+      SerializationOptions serialization_options =
+          SerializationOptions::DEFAULT);
 
   // Convert the given SerializedNavigationEntry into a NavigationEntry with the
   // given context.  The NavigationEntry will have a transition type of
diff --git a/components/sessions/content/content_serialized_navigation_builder_unittest.cc b/components/sessions/content/content_serialized_navigation_builder_unittest.cc
index 585c41d..45f365a2 100644
--- a/components/sessions/content/content_serialized_navigation_builder_unittest.cc
+++ b/components/sessions/content/content_serialized_navigation_builder_unittest.cc
@@ -161,6 +161,26 @@
             navigation.extended_info_map().at(kExtendedInfoKey2));
 }
 
+// Test effect of the navigation serialization options.
+TEST_F(ContentSerializedNavigationBuilderTest,
+       FromNavigationEntrySerializationOptions) {
+  const std::unique_ptr<content::NavigationEntry> navigation_entry(
+      MakeNavigationEntryForTest());
+
+  const SerializedNavigationEntry& default_navigation =
+      ContentSerializedNavigationBuilder::FromNavigationEntry(
+          test_data::kIndex, *navigation_entry,
+          ContentSerializedNavigationBuilder::DEFAULT);
+  EXPECT_EQ(test_data::kEncodedPageState,
+            default_navigation.encoded_page_state());
+
+  const SerializedNavigationEntry& excluded_page_state_navigation =
+      ContentSerializedNavigationBuilder::FromNavigationEntry(
+          test_data::kIndex, *navigation_entry,
+          ContentSerializedNavigationBuilder::EXCLUDE_PAGE_STATE);
+  EXPECT_TRUE(excluded_page_state_navigation.encoded_page_state().empty());
+}
+
 // Create a NavigationEntry, then create another one by converting to
 // a SerializedNavigationEntry and back.  The new one should match the old one
 // except for fields that aren't preserved, which should be set to
diff --git a/components/sync_sessions/task_tracker.cc b/components/sync_sessions/task_tracker.cc
index 3176f79..d8351cb 100644
--- a/components/sync_sessions/task_tracker.cc
+++ b/components/sync_sessions/task_tracker.cc
@@ -109,17 +109,30 @@
 TaskTracker::~TaskTracker() {}
 
 TabTasks* TaskTracker::GetTabTasks(SessionID::id_type tab_id,
-                                   SessionID::id_type parent_id) {
-  if (local_tab_tasks_map_.count(tab_id) > 0)
+                                   SessionID::id_type parent_tab_id) {
+  DVLOG(1) << "Getting tab tasks for " << tab_id << " with parent "
+           << parent_tab_id;
+  // If an existing TabTasks exists, attempt to reuse it. The caveat is that if
+  // a parent tab id is provided, it must match the parent tab id associated
+  // with the existing TabTasks. Otherwise a new TabTasks should be created from
+  // the specified parent. This is to handle the case where at the time the
+  // initial GetTabTasks is called, the parent id is not yet known, but it
+  // becomes known at a later time.
+  if (local_tab_tasks_map_.count(tab_id) > 0 &&
+      (parent_tab_id == kInvalidTabID ||
+       local_tab_tasks_map_[tab_id]->parent_tab_id() == parent_tab_id)) {
     return local_tab_tasks_map_[tab_id].get();
+  }
 
-  if (local_tab_tasks_map_.count(parent_id) > 0) {
+  DVLOG(1) << "Creating tab tasks for " << tab_id;
+  if (local_tab_tasks_map_.count(parent_tab_id) > 0) {
     // If the parent id is set, it means this tab forked from another tab.
     // In that case, the task for the current navigation might be part of a
     // larger task encompassing the parent tab. Perform a deep copy of the
     // parent's TabTasks object in order to simplify tracking this relationship.
     local_tab_tasks_map_[tab_id] =
-        base::MakeUnique<TabTasks>(*local_tab_tasks_map_[parent_id]);
+        base::MakeUnique<TabTasks>(*local_tab_tasks_map_[parent_tab_id]);
+    local_tab_tasks_map_[tab_id]->set_parent_tab_id(parent_tab_id);
   } else {
     local_tab_tasks_map_[tab_id] = base::MakeUnique<TabTasks>();
   }
diff --git a/components/sync_sessions/task_tracker.h b/components/sync_sessions/task_tracker.h
index bf79ab1..30f9320 100644
--- a/components/sync_sessions/task_tracker.h
+++ b/components/sync_sessions/task_tracker.h
@@ -16,6 +16,7 @@
 #include "base/time/time.h"
 #include "components/sessions/core/session_id.h"
 #include "components/sessions/core/session_types.h"
+#include "components/sync_sessions/synced_tab_delegate.h"
 #include "ui/base/page_transition_types.h"
 
 namespace sync_sessions {
@@ -40,6 +41,11 @@
   explicit TabTasks(const TabTasks& rhs);
   virtual ~TabTasks();
 
+  SessionID::id_type parent_tab_id() { return parent_tab_id_; }
+  void set_parent_tab_id(SessionID::id_type parent_tab_id) {
+    parent_tab_id_ = parent_tab_id;
+  }
+
   // Gets root->leaf task id list for the navigation denoted by |nav_id|.
   // Returns an empty vector if |nav_id| is not found.
   std::vector<int64_t> GetTaskIdsForNavigation(int nav_id) const;
@@ -77,6 +83,9 @@
   // The most recent navigation id seen for this tab.
   int most_recent_nav_id_ = kInvalidNavID;
 
+  // The parent id for this tab (if there is one).
+  SessionID::id_type parent_tab_id_ = kInvalidTabID;
+
   DISALLOW_ASSIGN(TabTasks);
 };
 
@@ -90,12 +99,12 @@
   virtual ~TaskTracker();
 
   // Returns a TabTasks pointer, which is owned by this object, for the tab of
-  // given |tab_id|. |parent_id|, if set, can be used to link the task ids
+  // given |tab_id|. |parent_tab_id|, if set, can be used to link the task ids
   // from one tab to another (e.g. when opening a navigation in a new tab, the
   // task ids from the original tab are necessary to continue tracking the
   // task chain).
   TabTasks* GetTabTasks(SessionID::id_type tab_id,
-                        SessionID::id_type parent_id);
+                        SessionID::id_type parent_tab_id);
 
   // Cleans tracked task ids of navigations in the tab of |tab_id|.
   void CleanTabTasks(SessionID::id_type tab_id);
diff --git a/components/sync_sessions/task_tracker_unittest.cc b/components/sync_sessions/task_tracker_unittest.cc
index 5db1094..be541ca 100644
--- a/components/sync_sessions/task_tracker_unittest.cc
+++ b/components/sync_sessions/task_tracker_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "components/sync_sessions/synced_tab_delegate.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -22,15 +23,15 @@
 
 TEST(TaskTrackerTest, GetTabTasks) {
   TaskTracker task_tracker;
-  TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidGlobalID);
+  TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidTabID);
   ASSERT_NE(tab_tasks, nullptr);
-  EXPECT_EQ(task_tracker.GetTabTasks(kTab1, kInvalidGlobalID), tab_tasks);
-  EXPECT_NE(task_tracker.GetTabTasks(kTab2, kInvalidGlobalID), tab_tasks);
+  EXPECT_EQ(task_tracker.GetTabTasks(kTab1, kInvalidTabID), tab_tasks);
+  EXPECT_NE(task_tracker.GetTabTasks(kTab2, kInvalidTabID), tab_tasks);
 }
 
 TEST(TaskTrackerTest, CleanTabTasks) {
   TaskTracker task_tracker;
-  TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidGlobalID);
+  TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidTabID);
   ASSERT_NE(tab_tasks, nullptr);
   ASSERT_FALSE(task_tracker.local_tab_tasks_map_.empty());
 
@@ -40,7 +41,7 @@
 
 TEST(TaskTrackerTest, UpdateTasksWithMultipleClicks) {
   TaskTracker task_tracker;
-  TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidGlobalID);
+  TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidTabID);
 
   tab_tasks->UpdateWithNavigation(1, ui::PageTransition::PAGE_TRANSITION_TYPED,
                                   100);
@@ -61,7 +62,7 @@
 
 TEST(TaskTrackerTest, UpdateTasksWithMultipleClicksAndTypes) {
   TaskTracker task_tracker;
-  TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidGlobalID);
+  TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidTabID);
 
   tab_tasks->UpdateWithNavigation(1, ui::PAGE_TRANSITION_LINK, 100);
   tab_tasks->UpdateWithNavigation(2, ui::PAGE_TRANSITION_LINK, 200);
@@ -83,7 +84,7 @@
 
 TEST(TaskTrackerTest, UpdateTasksWithBackforwards) {
   TaskTracker task_tracker;
-  TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidGlobalID);
+  TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidTabID);
 
   tab_tasks->UpdateWithNavigation(1, ui::PAGE_TRANSITION_TYPED, 100);
   tab_tasks->UpdateWithNavigation(2, ui::PAGE_TRANSITION_LINK, 200);
@@ -112,7 +113,7 @@
 
 TEST(TaskTrackerTest, UpdateWithNavigationsWithBackAndForkedNavigation) {
   TaskTracker task_tracker;
-  TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidGlobalID);
+  TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidTabID);
   tab_tasks->UpdateWithNavigation(1, ui::PAGE_TRANSITION_LINK, 100);
   tab_tasks->UpdateWithNavigation(2, ui::PAGE_TRANSITION_LINK, 200);
   tab_tasks->UpdateWithNavigation(3, ui::PAGE_TRANSITION_LINK, 300);
@@ -128,7 +129,7 @@
 
 TEST(TaskTrackerTest, LimitMaxNumberOfTasksPerTab) {
   TaskTracker task_tracker;
-  TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidGlobalID);
+  TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidTabID);
 
   // Reaching max number of tasks for a tab.
   for (int i = 1; i <= kMaxNumTasksPerTab; i++) {
@@ -163,8 +164,7 @@
 
 TEST(TaskTrackerTest, CreateTabTasksFromSourceTab) {
   TaskTracker task_tracker;
-  TabTasks* source_tab_tasks =
-      task_tracker.GetTabTasks(kTab1, kInvalidGlobalID);
+  TabTasks* source_tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidTabID);
   source_tab_tasks->UpdateWithNavigation(1, ui::PAGE_TRANSITION_LINK, 100);
   source_tab_tasks->UpdateWithNavigation(2, ui::PAGE_TRANSITION_LINK, 200);
   source_tab_tasks->UpdateWithNavigation(3, ui::PAGE_TRANSITION_TYPED, 300);
@@ -172,6 +172,7 @@
   source_tab_tasks->UpdateWithNavigation(5, ui::PAGE_TRANSITION_LINK, 500);
 
   TabTasks* target_tab_tasks = task_tracker.GetTabTasks(kTab2, kTab1);
+  EXPECT_EQ(kTab1, target_tab_tasks->parent_tab_id());
   target_tab_tasks->UpdateWithNavigation(6, ui::PAGE_TRANSITION_LINK, 600);
   target_tab_tasks->UpdateWithNavigation(7, ui::PAGE_TRANSITION_LINK, 700);
   target_tab_tasks->UpdateWithNavigation(8, ui::PAGE_TRANSITION_TYPED, 800);
@@ -185,8 +186,7 @@
 
 TEST(TaskTrackerTest, CreateTabTasksFromSourceTabAfterGoingBack) {
   TaskTracker task_tracker;
-  TabTasks* source_tab_tasks =
-      task_tracker.GetTabTasks(kTab1, kInvalidGlobalID);
+  TabTasks* source_tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidTabID);
   source_tab_tasks->UpdateWithNavigation(1, ui::PAGE_TRANSITION_LINK, 100);
   source_tab_tasks->UpdateWithNavigation(2, ui::PAGE_TRANSITION_LINK, 200);
   source_tab_tasks->UpdateWithNavigation(3, ui::PAGE_TRANSITION_TYPED, 300);
@@ -201,6 +201,7 @@
               ElementsAre(100, 200));
 
   TabTasks* target_tab_tasks = task_tracker.GetTabTasks(kTab2, kTab1);
+  EXPECT_EQ(kTab1, target_tab_tasks->parent_tab_id());
   target_tab_tasks->UpdateWithNavigation(7, ui::PAGE_TRANSITION_LINK, 700);
 
   EXPECT_THAT(target_tab_tasks->GetTaskIdsForNavigation(7),
@@ -210,8 +211,7 @@
 TEST(TaskTrackerTest, CreateTabTasksFromSourceTabWithLimitedTaskNum) {
   TaskTracker task_tracker;
 
-  TabTasks* source_tab_tasks =
-      task_tracker.GetTabTasks(kTab1, kInvalidGlobalID);
+  TabTasks* source_tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidTabID);
   // Adding max number of tasks to tab1.
   int nav_id = 1;
   for (; nav_id <= kMaxNumTasksPerTab; nav_id++) {
@@ -220,6 +220,7 @@
   }
 
   TabTasks* tab_tasks = task_tracker.GetTabTasks(kTab2, kTab1);
+  EXPECT_EQ(kTab1, tab_tasks->parent_tab_id());
   tab_tasks->UpdateWithNavigation(nav_id, ui::PAGE_TRANSITION_LINK,
                                   nav_id * 100);
 
@@ -233,4 +234,29 @@
               ElementsAreArray(expected_task_ids, kMaxNumTasksPerTab));
 }
 
+TEST(TaskTrackerTest, GetTabTasksWithNewSource) {
+  TaskTracker task_tracker;
+  TabTasks* target_tab_tasks = task_tracker.GetTabTasks(kTab2, kInvalidTabID);
+  EXPECT_EQ(kInvalidTabID, target_tab_tasks->parent_tab_id());
+
+  TabTasks* source_tab_tasks = task_tracker.GetTabTasks(kTab1, kInvalidTabID);
+  source_tab_tasks->UpdateWithNavigation(1, ui::PAGE_TRANSITION_LINK, 100);
+  source_tab_tasks->UpdateWithNavigation(2, ui::PAGE_TRANSITION_LINK, 200);
+  source_tab_tasks->UpdateWithNavigation(3, ui::PAGE_TRANSITION_TYPED, 300);
+  source_tab_tasks->UpdateWithNavigation(4, ui::PAGE_TRANSITION_LINK, 400);
+  source_tab_tasks->UpdateWithNavigation(5, ui::PAGE_TRANSITION_LINK, 500);
+
+  target_tab_tasks = task_tracker.GetTabTasks(kTab2, kTab1);
+  EXPECT_EQ(kTab1, target_tab_tasks->parent_tab_id());
+  target_tab_tasks->UpdateWithNavigation(6, ui::PAGE_TRANSITION_LINK, 600);
+  target_tab_tasks->UpdateWithNavigation(7, ui::PAGE_TRANSITION_LINK, 700);
+  target_tab_tasks->UpdateWithNavigation(8, ui::PAGE_TRANSITION_TYPED, 800);
+
+  EXPECT_THAT(target_tab_tasks->GetTaskIdsForNavigation(6),
+              ElementsAre(300, 400, 500, 600));
+  EXPECT_THAT(target_tab_tasks->GetTaskIdsForNavigation(7),
+              ElementsAre(300, 400, 500, 600, 700));
+  EXPECT_THAT(target_tab_tasks->GetTaskIdsForNavigation(8), ElementsAre(800));
+}
+
 }  // namespace sync_sessions
diff --git a/components/variations/service/BUILD.gn b/components/variations/service/BUILD.gn
index d2ea94f1..6e8da5d 100644
--- a/components/variations/service/BUILD.gn
+++ b/components/variations/service/BUILD.gn
@@ -38,6 +38,8 @@
     ":service",
     "//base",
     "//base/test:test_support",
+    "//components/metrics",
+    "//components/metrics:test_support",
     "//components/prefs:test_support",
     "//components/variations",
     "//components/variations/proto",
diff --git a/components/variations/service/variations_service.cc b/components/variations/service/variations_service.cc
index e6c32d9..acdf7ef 100644
--- a/components/variations/service/variations_service.cc
+++ b/components/variations/service/variations_service.cc
@@ -59,6 +59,10 @@
 // Maximum age permitted for a variations seed, in days.
 const int kMaxVariationsSeedAgeDays = 30;
 
+// Whether the VariationsService should always be created, even in Chromium
+// builds.
+bool g_enabled_for_testing = false;
+
 // Wrapper around channel checking, used to enable channel mocking for
 // testing. If the current browser channel is not UNKNOWN, this will return
 // that channel value. Otherwise, if the fake channel flag is provided, this
@@ -488,7 +492,8 @@
   // Unless the URL was provided, unsupported builds should return NULL to
   // indicate that the service should not be used.
   if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
-          switches::kVariationsServerURL)) {
+          switches::kVariationsServerURL) &&
+      !g_enabled_for_testing) {
     DVLOG(1) << "Not creating VariationsService in unofficial build without --"
              << switches::kVariationsServerURL << " specified.";
     return result;
@@ -503,14 +508,8 @@
 }
 
 // static
-std::unique_ptr<VariationsService> VariationsService::CreateForTesting(
-    std::unique_ptr<VariationsServiceClient> client,
-    PrefService* local_state) {
-  return base::WrapUnique(new VariationsService(
-      std::move(client),
-      base::MakeUnique<web_resource::ResourceRequestAllowedNotifier>(
-          local_state, nullptr),
-      local_state, nullptr, UIStringOverrider()));
+void VariationsService::EnableForTesting() {
+  g_enabled_for_testing = true;
 }
 
 void VariationsService::DoActualFetch() {
@@ -598,11 +597,6 @@
   }
   RecordLastFetchTime();
 
-  // Perform seed simulation only if |state_manager_| is not-NULL. The state
-  // manager may be NULL for some unit tests.
-  if (!state_manager_)
-    return true;
-
   base::PostTaskWithTraitsAndReplyWithResult(
       FROM_HERE, {base::MayBlock(), base::TaskPriority::BACKGROUND},
       client_->GetVersionForSimulationCallback(),
@@ -808,11 +802,8 @@
 void VariationsService::RecordLastFetchTime() {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  // local_state_ is NULL in tests, so check it first.
-  if (local_state_) {
-    local_state_->SetInt64(prefs::kVariationsLastFetchTime,
-                           base::Time::Now().ToInternalValue());
-  }
+  local_state_->SetInt64(prefs::kVariationsLastFetchTime,
+                         base::Time::Now().ToInternalValue());
 }
 
 std::string VariationsService::GetInvalidVariationsSeedSignature() const {
diff --git a/components/variations/service/variations_service.h b/components/variations/service/variations_service.h
index fdc7dad7..f3bf46b 100644
--- a/components/variations/service/variations_service.h
+++ b/components/variations/service/variations_service.h
@@ -152,10 +152,8 @@
       const char* disable_network_switch,
       const UIStringOverrider& ui_string_overrider);
 
-  // Factory method for creating a VariationsService in a testing context.
-  static std::unique_ptr<VariationsService> CreateForTesting(
-      std::unique_ptr<VariationsServiceClient> client,
-      PrefService* local_state);
+  // Enables the VariationsService for testing, even in Chromium builds.
+  static void EnableForTesting();
 
   // Set the PrefService responsible for getting policy-related preferences,
   // such as the restrict parameter.
diff --git a/components/variations/service/variations_service_unittest.cc b/components/variations/service/variations_service_unittest.cc
index f9d523b..181a1926 100644
--- a/components/variations/service/variations_service_unittest.cc
+++ b/components/variations/service/variations_service_unittest.cc
@@ -22,6 +22,10 @@
 #include "base/strings/string_util.h"
 #include "base/test/histogram_tester.h"
 #include "base/version.h"
+#include "components/metrics/clean_exit_beacon.h"
+#include "components/metrics/client_info.h"
+#include "components/metrics/metrics_state_manager.h"
+#include "components/metrics/test_enabled_state_provider.h"
 #include "components/prefs/testing_pref_service.h"
 #include "components/variations/pref_names.h"
 #include "components/variations/proto/study.pb.h"
@@ -36,6 +40,14 @@
 namespace variations {
 namespace {
 
+// A stub for the metrics state manager.
+void StubStoreClientInfo(const metrics::ClientInfo& /* client_info */) {}
+
+// A stub for the metrics state manager.
+std::unique_ptr<metrics::ClientInfo> StubLoadClientInfo() {
+  return std::unique_ptr<metrics::ClientInfo>();
+}
+
 class TestVariationsServiceClient : public VariationsServiceClient {
  public:
   TestVariationsServiceClient() {}
@@ -78,11 +90,12 @@
  public:
   TestVariationsService(
       std::unique_ptr<web_resource::TestRequestAllowedNotifier> test_notifier,
-      PrefService* local_state)
+      PrefService* local_state,
+      metrics::MetricsStateManager* state_manager)
       : VariationsService(base::WrapUnique(new TestVariationsServiceClient()),
                           std::move(test_notifier),
                           local_state,
-                          NULL,
+                          state_manager,
                           UIStringOverrider()),
         intercepts_fetch_(true),
         fetch_attempted_(false),
@@ -156,9 +169,7 @@
 class TestVariationsServiceObserver : public VariationsService::Observer {
  public:
   TestVariationsServiceObserver()
-      : best_effort_changes_notified_(0),
-        crticial_changes_notified_(0) {
-  }
+      : best_effort_changes_notified_(0), crticial_changes_notified_(0) {}
   ~TestVariationsServiceObserver() override {}
 
   void OnExperimentChangesDetected(Severity severity) override {
@@ -257,33 +268,52 @@
 
 class VariationsServiceTest : public ::testing::Test {
  protected:
-  VariationsServiceTest() {}
+  VariationsServiceTest()
+      : enabled_state_provider_(
+            new metrics::TestEnabledStateProvider(false, false)) {
+    VariationsService::RegisterPrefs(prefs_.registry());
+    metrics::CleanExitBeacon::RegisterPrefs(prefs_.registry());
+    metrics::MetricsStateManager::RegisterPrefs(prefs_.registry());
+  }
+
+  metrics::MetricsStateManager* GetMetricsStateManager() {
+    // Lazy-initialize the metrics_state_manager so that it correctly reads the
+    // stability state from prefs after tests have a chance to initialize it.
+    if (!metrics_state_manager_) {
+      metrics_state_manager_ = metrics::MetricsStateManager::Create(
+          &prefs_, enabled_state_provider_.get(), base::string16(),
+          base::Bind(&StubStoreClientInfo), base::Bind(&StubLoadClientInfo));
+    }
+    return metrics_state_manager_.get();
+  }
+
+ protected:
+  TestingPrefServiceSimple prefs_;
 
  private:
   base::MessageLoop message_loop_;
+  std::unique_ptr<metrics::TestEnabledStateProvider> enabled_state_provider_;
+  std::unique_ptr<metrics::MetricsStateManager> metrics_state_manager_;
 
   DISALLOW_COPY_AND_ASSIGN(VariationsServiceTest);
 };
 
 TEST_F(VariationsServiceTest, CreateTrialsFromSeed) {
-  TestingPrefServiceSimple prefs;
-  VariationsService::RegisterPrefs(prefs.registry());
-
   // Create a local base::FieldTrialList, to hold the field trials created in
   // this test.
   base::FieldTrialList field_trial_list(nullptr);
 
   // Create a variations service.
   TestVariationsService service(
-      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs),
-      &prefs);
+      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs_),
+      &prefs_, GetMetricsStateManager());
   service.SetCreateTrialsFromSeedCalledForTesting(false);
 
   // Store a seed.
   service.StoreSeed(SerializeSeed(CreateTestSeed()), std::string(),
                     std::string(), base::Time::Now(), false, false);
-  prefs.SetInt64(prefs::kVariationsLastFetchTime,
-                 base::Time::Now().ToInternalValue());
+  prefs_.SetInt64(prefs::kVariationsLastFetchTime,
+                  base::Time::Now().ToInternalValue());
 
   // Check that field trials are created from the seed. Since the test study has
   // only 1 experiment with 100% probability weight, we must be part of it.
@@ -293,24 +323,21 @@
 }
 
 TEST_F(VariationsServiceTest, CreateTrialsFromSeedNoLastFetchTime) {
-  TestingPrefServiceSimple prefs;
-  VariationsService::RegisterPrefs(prefs.registry());
-
   // Create a local base::FieldTrialList, to hold the field trials created in
   // this test.
   base::FieldTrialList field_trial_list(nullptr);
 
   // Create a variations service
   TestVariationsService service(
-      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs),
-      &prefs);
+      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs_),
+      &prefs_, GetMetricsStateManager());
   service.SetCreateTrialsFromSeedCalledForTesting(false);
 
   // Store a seed. To simulate a first run, |prefs::kVariationsLastFetchTime|
   // is left empty.
   service.StoreSeed(SerializeSeed(CreateTestSeed()), std::string(),
                     std::string(), base::Time::Now(), false, false);
-  EXPECT_EQ(0, prefs.GetInt64(prefs::kVariationsLastFetchTime));
+  EXPECT_EQ(0, prefs_.GetInt64(prefs::kVariationsLastFetchTime));
 
   // Check that field trials are created from the seed. Since the test study has
   // only 1 experiment with 100% probability weight, we must be part of it.
@@ -320,17 +347,14 @@
 }
 
 TEST_F(VariationsServiceTest, CreateTrialsFromOutdatedSeed) {
-  TestingPrefServiceSimple prefs;
-  VariationsService::RegisterPrefs(prefs.registry());
-
   // Create a local base::FieldTrialList, to hold the field trials created in
   // this test.
   base::FieldTrialList field_trial_list(nullptr);
 
   // Create a variations service.
   TestVariationsService service(
-      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs),
-      &prefs);
+      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs_),
+      &prefs_, GetMetricsStateManager());
   service.SetCreateTrialsFromSeedCalledForTesting(false);
 
   // Store a seed, with a fetch time 31 days in the past.
@@ -338,7 +362,7 @@
       base::Time::Now() - base::TimeDelta::FromDays(31);
   service.StoreSeed(SerializeSeed(CreateTestSeed()), std::string(),
                     std::string(), seed_date, false, false);
-  prefs.SetInt64(prefs::kVariationsLastFetchTime, seed_date.ToInternalValue());
+  prefs_.SetInt64(prefs::kVariationsLastFetchTime, seed_date.ToInternalValue());
 
   // Check that field trials are not created from the seed.
   EXPECT_FALSE(service.CreateTrialsFromSeed(base::FeatureList::GetInstance()));
@@ -346,8 +370,6 @@
 }
 
 TEST_F(VariationsServiceTest, GetVariationsServerURL) {
-  TestingPrefServiceSimple prefs;
-  VariationsService::RegisterPrefs(prefs.registry());
   const std::string default_variations_url =
       VariationsService::GetDefaultVariationsServerURLForTesting();
 
@@ -357,31 +379,31 @@
   TestVariationsServiceClient* raw_client = client.get();
   VariationsService service(
       std::move(client),
-      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs),
-      &prefs, NULL, UIStringOverrider());
-  GURL url = service.GetVariationsServerURL(&prefs, std::string());
+      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs_),
+      &prefs_, GetMetricsStateManager(), UIStringOverrider());
+  GURL url = service.GetVariationsServerURL(&prefs_, std::string());
   EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url,
                                base::CompareCase::SENSITIVE));
   EXPECT_FALSE(net::GetValueForKeyInQuery(url, "restrict", &value));
 
-  prefs.SetString(prefs::kVariationsRestrictParameter, "restricted");
-  url = service.GetVariationsServerURL(&prefs, std::string());
+  prefs_.SetString(prefs::kVariationsRestrictParameter, "restricted");
+  url = service.GetVariationsServerURL(&prefs_, std::string());
   EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url,
                                base::CompareCase::SENSITIVE));
   EXPECT_TRUE(net::GetValueForKeyInQuery(url, "restrict", &value));
   EXPECT_EQ("restricted", value);
 
-  // A client override should take precedence over what's in prefs.
+  // A client override should take precedence over what's in prefs_.
   raw_client->set_restrict_parameter("client");
-  url = service.GetVariationsServerURL(&prefs, std::string());
+  url = service.GetVariationsServerURL(&prefs_, std::string());
   EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url,
                                base::CompareCase::SENSITIVE));
   EXPECT_TRUE(net::GetValueForKeyInQuery(url, "restrict", &value));
   EXPECT_EQ("client", value);
 
   // The override value passed to the method should take precedence over
-  // what's in prefs and a client override.
-  url = service.GetVariationsServerURL(&prefs, "override");
+  // what's in prefs_ and a client override.
+  url = service.GetVariationsServerURL(&prefs_, "override");
   EXPECT_TRUE(base::StartsWith(url.spec(), default_variations_url,
                                base::CompareCase::SENSITIVE));
   EXPECT_TRUE(net::GetValueForKeyInQuery(url, "restrict", &value));
@@ -389,12 +411,10 @@
 }
 
 TEST_F(VariationsServiceTest, VariationsURLHasOSNameParam) {
-  TestingPrefServiceSimple prefs;
-  VariationsService::RegisterPrefs(prefs.registry());
   TestVariationsService service(
-      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs),
-      &prefs);
-  const GURL url = service.GetVariationsServerURL(&prefs, std::string());
+      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs_),
+      &prefs_, GetMetricsStateManager());
+  const GURL url = service.GetVariationsServerURL(&prefs_, std::string());
 
   std::string value;
   EXPECT_TRUE(net::GetValueForKeyInQuery(url, "osname", &value));
@@ -402,15 +422,13 @@
 }
 
 TEST_F(VariationsServiceTest, RequestsInitiallyNotAllowed) {
-  TestingPrefServiceSimple prefs;
-  VariationsService::RegisterPrefs(prefs.registry());
-
   // Pass ownership to TestVariationsService, but keep a weak pointer to
   // manipulate it for this test.
   std::unique_ptr<web_resource::TestRequestAllowedNotifier> test_notifier =
-      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs);
+      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs_);
   web_resource::TestRequestAllowedNotifier* raw_notifier = test_notifier.get();
-  TestVariationsService test_service(std::move(test_notifier), &prefs);
+  TestVariationsService test_service(std::move(test_notifier), &prefs_,
+                                     GetMetricsStateManager());
 
   // Force the notifier to initially disallow requests.
   raw_notifier->SetRequestsAllowedOverride(false);
@@ -422,15 +440,13 @@
 }
 
 TEST_F(VariationsServiceTest, RequestsInitiallyAllowed) {
-  TestingPrefServiceSimple prefs;
-  VariationsService::RegisterPrefs(prefs.registry());
-
   // Pass ownership to TestVariationsService, but keep a weak pointer to
   // manipulate it for this test.
   std::unique_ptr<web_resource::TestRequestAllowedNotifier> test_notifier =
-      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs);
+      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs_);
   web_resource::TestRequestAllowedNotifier* raw_notifier = test_notifier.get();
-  TestVariationsService test_service(std::move(test_notifier), &prefs);
+  TestVariationsService test_service(std::move(test_notifier), &prefs_,
+                                     GetMetricsStateManager());
 
   raw_notifier->SetRequestsAllowedOverride(true);
   test_service.StartRepeatedVariationsSeedFetch();
@@ -438,12 +454,9 @@
 }
 
 TEST_F(VariationsServiceTest, SeedStoredWhenOKStatus) {
-  TestingPrefServiceSimple prefs;
-  VariationsService::RegisterPrefs(prefs.registry());
-
   TestVariationsService service(
-      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs),
-      &prefs);
+      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs_),
+      &prefs_, GetMetricsStateManager());
   service.set_intercepts_fetch(false);
 
   net::TestURLFetcherFactory factory;
@@ -467,36 +480,31 @@
     net::HTTP_SERVICE_UNAVAILABLE,
   };
 
-  TestingPrefServiceSimple prefs;
-  VariationsService::RegisterPrefs(prefs.registry());
-
   TestVariationsService service(
-      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs),
-      &prefs);
+      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs_),
+      &prefs_, GetMetricsStateManager());
   service.set_intercepts_fetch(false);
   for (size_t i = 0; i < arraysize(non_ok_status_codes); ++i) {
     net::TestURLFetcherFactory factory;
     service.DoActualFetch();
-    EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsCompressedSeed)
+    EXPECT_TRUE(prefs_.FindPreference(prefs::kVariationsCompressedSeed)
                     ->IsDefaultValue());
 
     net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
     SimulateServerResponse(non_ok_status_codes[i], fetcher);
     service.OnURLFetchComplete(fetcher);
 
-    EXPECT_TRUE(prefs.FindPreference(prefs::kVariationsCompressedSeed)
+    EXPECT_TRUE(prefs_.FindPreference(prefs::kVariationsCompressedSeed)
                     ->IsDefaultValue());
   }
 }
 
 TEST_F(VariationsServiceTest, RequestGzipCompressedSeed) {
-  TestingPrefServiceSimple prefs;
-  VariationsService::RegisterPrefs(prefs.registry());
   net::TestURLFetcherFactory factory;
 
   TestVariationsService service(
-      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs),
-      &prefs);
+      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs_),
+      &prefs_, GetMetricsStateManager());
   service.set_intercepts_fetch(false);
   service.DoActualFetch();
 
@@ -524,15 +532,13 @@
     {"IM:deflate,x-bm,gzip", false, false, false},
   };
 
-  TestingPrefServiceSimple prefs;
-  VariationsService::RegisterPrefs(prefs.registry());
   std::string serialized_seed = SerializeSeed(CreateTestSeed());
   net::TestURLFetcherFactory factory;
 
   for (size_t i = 0; i < arraysize(cases); ++i) {
     TestVariationsService service(
-        base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs),
-        &prefs);
+        base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs_),
+        &prefs_, GetMetricsStateManager());
     service.set_intercepts_fetch(false);
     service.DoActualFetch();
     net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
@@ -551,12 +557,9 @@
 }
 
 TEST_F(VariationsServiceTest, CountryHeader) {
-  TestingPrefServiceSimple prefs;
-  VariationsService::RegisterPrefs(prefs.registry());
-
   TestVariationsService service(
-      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs),
-      &prefs);
+      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs_),
+      &prefs_, GetMetricsStateManager());
   service.set_intercepts_fetch(false);
 
   net::TestURLFetcherFactory factory;
@@ -575,12 +578,10 @@
 }
 
 TEST_F(VariationsServiceTest, Observer) {
-  TestingPrefServiceSimple prefs;
-  VariationsService::RegisterPrefs(prefs.registry());
   VariationsService service(
       base::MakeUnique<TestVariationsServiceClient>(),
-      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs),
-      &prefs, NULL, UIStringOverrider());
+      base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs_),
+      &prefs_, GetMetricsStateManager(), UIStringOverrider());
 
   struct {
     int normal_count;
@@ -675,21 +676,21 @@
   };
 
   for (const auto& test : test_cases) {
-    TestingPrefServiceSimple prefs;
-    VariationsService::RegisterPrefs(prefs.registry());
     VariationsService service(
         base::MakeUnique<TestVariationsServiceClient>(),
-        base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs),
-        &prefs, NULL, UIStringOverrider());
+        base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs_),
+        &prefs_, GetMetricsStateManager(), UIStringOverrider());
 
-    if (test.pref_value_before) {
+    if (!test.pref_value_before) {
+      prefs_.ClearPref(prefs::kVariationsPermanentConsistencyCountry);
+    } else {
       base::ListValue list_value;
       for (const std::string& component :
            base::SplitString(test.pref_value_before, ",", base::TRIM_WHITESPACE,
                              base::SPLIT_WANT_ALL)) {
         list_value.AppendString(component);
       }
-      prefs.Set(prefs::kVariationsPermanentConsistencyCountry, list_value);
+      prefs_.Set(prefs::kVariationsPermanentConsistencyCountry, list_value);
     }
 
     VariationsSeed seed(CreateTestSeed());
@@ -711,7 +712,7 @@
       expected_list_value.AppendString(component);
     }
     const base::ListValue* pref_value =
-        prefs.GetList(prefs::kVariationsPermanentConsistencyCountry);
+        prefs_.GetList(prefs::kVariationsPermanentConsistencyCountry);
     EXPECT_EQ(ListValueToString(expected_list_value),
               ListValueToString(*pref_value))
         << test.pref_value_before << ", " << test.version << ", "
@@ -747,20 +748,20 @@
   };
 
   for (const auto& test : test_cases) {
-    TestingPrefServiceSimple prefs;
-    VariationsService::RegisterPrefs(prefs.registry());
     TestVariationsService service(
-        base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs),
-        &prefs);
+        base::MakeUnique<web_resource::TestRequestAllowedNotifier>(&prefs_),
+        &prefs_, GetMetricsStateManager());
 
-    if (!test.pref_value_before.empty()) {
+    if (test.pref_value_before.empty()) {
+      prefs_.ClearPref(prefs::kVariationsPermanentConsistencyCountry);
+    } else {
       base::ListValue list_value;
       for (const std::string& component :
            base::SplitString(test.pref_value_before, ",", base::TRIM_WHITESPACE,
                              base::SPLIT_WANT_ALL)) {
         list_value.AppendString(component);
       }
-      prefs.Set(prefs::kVariationsPermanentConsistencyCountry, list_value);
+      prefs_.Set(prefs::kVariationsPermanentConsistencyCountry, list_value);
     }
 
     VariationsSeed seed(CreateTestSeed());
@@ -776,7 +777,7 @@
       expected_list_value.AppendString(component);
     }
     const base::ListValue* pref_value =
-        prefs.GetList(prefs::kVariationsPermanentConsistencyCountry);
+        prefs_.GetList(prefs::kVariationsPermanentConsistencyCountry);
     EXPECT_EQ(ListValueToString(expected_list_value),
               ListValueToString(*pref_value))
         << test.pref_value_before << ", " << test.country_code_override;
diff --git a/components/viz/BUILD.gn b/components/viz/BUILD.gn
index e02e4340..2795882 100644
--- a/components/viz/BUILD.gn
+++ b/components/viz/BUILD.gn
@@ -2,23 +2,55 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//components/viz/viz.gni")
 import("//testing/test.gni")
 
-test("viz_unittests") {
+viz_test("viz_unittests") {
   sources = [
-    "run_all_unittests.cc",
+    "test/run_all_unittests.cc",
+  ]
+  deps = [
+    "//base",
+    "//base/test:test_support",
+    "//components/viz/common:unit_tests",
+    "//components/viz/host:unit_tests",
+    "//components/viz/service:unit_tests",
+    "//components/viz/test:test_suite",
+    "//components/viz/test:test_support",
+    "//mojo/edk/system",
+  ]
+
+  if (!is_android) {
+    data = [
+      "test/data/",
+    ]
+  }
+
+  data_deps = [
+    "//third_party/mesa:osmesa",
+  ]
+}
+
+viz_test("viz_perftests") {
+  sources = [
+    "test/run_all_perftests.cc",
   ]
 
   deps = [
     "//base",
     "//base/test:test_support",
-    "//components/viz/host:unit_tests",
-    "//components/viz/service:unit_tests",
-    "//mojo/edk/system",
-    "//ui/gl:test_support",
+    "//components/viz/service:perf_tests",
+    "//components/viz/test:test_suite",
   ]
 
-  if (!is_android) {
-    deps += [ "//components/viz/common:unit_tests" ]
-  }
+  # This target should not require the Chrome executable to run.
+  assert_no_deps = [ "//chrome" ]
+
+  data = [
+    # Needed for isolate script to execute.
+    "//testing/scripts/common.py",
+    "//testing/xvfb.py",
+    "//testing/scripts/run_gtest_perf_test.py",
+    "//tools/perf/generate_legacy_perf_dashboard_json.py",
+  ]
 }
diff --git a/components/viz/client/BUILD.gn b/components/viz/client/BUILD.gn
index a2ce3fb..1c97eed 100644
--- a/components/viz/client/BUILD.gn
+++ b/components/viz/client/BUILD.gn
@@ -2,7 +2,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-source_set("client") {
+import("//components/viz/viz.gni")
+
+viz_source_set("client") {
   sources = [
     "client_layer_tree_frame_sink.cc",
     "client_layer_tree_frame_sink.h",
diff --git a/components/viz/common/BUILD.gn b/components/viz/common/BUILD.gn
index c9051b6..8b990b74e 100644
--- a/components/viz/common/BUILD.gn
+++ b/components/viz/common/BUILD.gn
@@ -2,9 +2,10 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//components/viz/viz.gni")
 import("//testing/test.gni")
 
-source_set("common") {
+viz_source_set("common") {
   sources = [
     "frame_sink_id.cc",
     "frame_sink_id.h",
@@ -52,9 +53,7 @@
   ]
 }
 
-# These tests don't pass on Android so this target isn't in viz_unittests. If
-# you add a test here that should run on Android you need to change that.
-source_set("unit_tests") {
+viz_source_set("unit_tests") {
   testonly = true
   sources = [
     "gl_helper_unittest.cc",
@@ -77,12 +76,12 @@
 
 # Microbenchmark to measure performance of GLHelper code, for use in
 # debugging, profiling, and optimizing.
-test("viz_benchmark") {
+viz_test("viz_benchmark") {
   sources = [
     "gl_helper_benchmark.cc",
   ]
 
-  configs += [
+  configs = [
     "//build/config/compiler:no_size_t_to_int_warning",
     "//third_party/khronos:khronos_headers",
   ]
diff --git a/components/viz/common/gl_helper_unittest.cc b/components/viz/common/gl_helper_unittest.cc
index 923787b..34192b48 100644
--- a/components/viz/common/gl_helper_unittest.cc
+++ b/components/viz/common/gl_helper_unittest.cc
@@ -17,12 +17,12 @@
 #include "base/bind.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted_memory.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
 #include "base/synchronization/waitable_event.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/time/time.h"
+#include "build/build_config.h"
 #include "components/viz/common/gl_helper.h"
 #include "components/viz/common/gl_helper_readback_support.h"
 #include "components/viz/common/gl_helper_scaling.h"
@@ -33,6 +33,8 @@
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "third_party/skia/include/core/SkTypes.h"
 
+#if !defined(OS_ANDROID)
+
 namespace viz {
 
 GLHelper::ScalerQuality kQualities[] = {
@@ -1248,7 +1250,6 @@
   std::unique_ptr<GLHelper> helper_;
   std::unique_ptr<GLHelperScaling> helper_scaling_;
   std::deque<GLHelperScaling::ScaleOp> x_ops_, y_ops_;
-  base::MessageLoop message_loop_;
 };
 
 class GLHelperPixelTest : public GLHelperTest {
@@ -1420,3 +1421,5 @@
 }
 
 }  // namespace viz
+
+#endif  // OS_ANDROID
diff --git a/components/viz/common/yuv_readback_unittest.cc b/components/viz/common/yuv_readback_unittest.cc
index de4c608..3a92257a 100644
--- a/components/viz/common/yuv_readback_unittest.cc
+++ b/components/viz/common/yuv_readback_unittest.cc
@@ -6,9 +6,9 @@
 #include "base/memory/ref_counted_memory.h"
 #include "base/run_loop.h"
 #include "base/strings/stringprintf.h"
-#include "base/test/scoped_task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "base/trace_event/trace_event.h"
+#include "build/build_config.h"
 #include "components/viz/common/gl_helper.h"
 #include "gpu/command_buffer/client/gles2_implementation.h"
 #include "gpu/command_buffer/client/shared_memory_limits.h"
@@ -19,6 +19,8 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 
+#if !defined(OS_ANDROID)
+
 namespace viz {
 
 namespace {
@@ -470,7 +472,6 @@
     gl_->DeleteTextures(1, &src_texture);
   }
 
-  base::test::ScopedTaskEnvironment scoped_task_environment_;
   std::unique_ptr<gpu::GLInProcessContext> context_;
   gpu::gles2::GLES2Interface* gl_;
   std::unique_ptr<GLHelper> helper_;
@@ -553,3 +554,5 @@
         ::testing::Range<unsigned int>(0, arraysize(kYUVReadbackSizes))));
 
 }  // namespace viz
+
+#endif
diff --git a/components/viz/host/BUILD.gn b/components/viz/host/BUILD.gn
index e928add..7995512 100644
--- a/components/viz/host/BUILD.gn
+++ b/components/viz/host/BUILD.gn
@@ -2,7 +2,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-component("host") {
+import("//components/viz/viz.gni")
+
+viz_component("host") {
   defines = [ "VIZ_HOST_IMPLEMENTATION" ]
 
   sources = [
@@ -29,7 +31,7 @@
   ]
 }
 
-source_set("unit_tests") {
+viz_source_set("unit_tests") {
   testonly = true
 
   sources = [
diff --git a/components/viz/host/host_frame_sink_manager_unittests.cc b/components/viz/host/host_frame_sink_manager_unittests.cc
index 7e1bdad..dcc68f9 100644
--- a/components/viz/host/host_frame_sink_manager_unittests.cc
+++ b/components/viz/host/host_frame_sink_manager_unittests.cc
@@ -8,7 +8,6 @@
 #include <utility>
 
 #include "base/macros.h"
-#include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "cc/ipc/frame_sink_manager.mojom.h"
 #include "components/viz/common/frame_sink_id.h"
@@ -122,7 +121,6 @@
   }
 
  private:
-  base::MessageLoop message_loop_;
   std::unique_ptr<HostFrameSinkManager> host_manager_;
   std::unique_ptr<MockFrameSinkManagerImpl> manager_impl_;
 
diff --git a/components/viz/host/server_gpu_memory_buffer_manager_unittest.cc b/components/viz/host/server_gpu_memory_buffer_manager_unittest.cc
index 12fb5087..6737f18f 100644
--- a/components/viz/host/server_gpu_memory_buffer_manager_unittest.cc
+++ b/components/viz/host/server_gpu_memory_buffer_manager_unittest.cc
@@ -4,7 +4,7 @@
 
 #include "components/viz/host/server_gpu_memory_buffer_manager.h"
 
-#include "base/test/scoped_task_environment.h"
+#include "base/run_loop.h"
 #include "base/threading/thread.h"
 #include "gpu/ipc/host/gpu_memory_buffer_support.h"
 #include "services/ui/gpu/interfaces/gpu_service.mojom.h"
@@ -169,7 +169,6 @@
   void TearDown() override { gfx::ClientNativePixmapFactory::ResetInstance(); }
 
  private:
-  base::test::ScopedTaskEnvironment env_;
   FakeClientNativePixmapFactory pixmap_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ServerGpuMemoryBufferManagerTest);
diff --git a/components/viz/run_all_unittests.cc b/components/viz/run_all_unittests.cc
deleted file mode 100644
index 03910b9..0000000
--- a/components/viz/run_all_unittests.cc
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/bind.h"
-#include "base/test/launcher/unit_test_launcher.h"
-#include "base/test/test_suite.h"
-#include "mojo/edk/embedder/embedder.h"
-#include "ui/gl/test/gl_surface_test_support.h"
-
-namespace {
-
-class VizTestSuite : public base::TestSuite {
- public:
-  VizTestSuite(int argc, char** argv) : base::TestSuite(argc, argv) {}
-  ~VizTestSuite() override = default;
-
-  // base::TestSuite:
-  void Initialize() override {
-    base::TestSuite::Initialize();
-    gl::GLSurfaceTestSupport::InitializeOneOff();
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(VizTestSuite);
-};
-
-}  // namespace
-
-int main(int argc, char** argv) {
-  VizTestSuite test_suite(argc, argv);
-
-  mojo::edk::Init();
-
-  return base::LaunchUnitTests(
-      argc, argv,
-      base::Bind(&VizTestSuite::Run, base::Unretained(&test_suite)));
-}
diff --git a/components/viz/service/BUILD.gn b/components/viz/service/BUILD.gn
index 2516ef2..40cd8fc 100644
--- a/components/viz/service/BUILD.gn
+++ b/components/viz/service/BUILD.gn
@@ -3,12 +3,20 @@
 # found in the LICENSE file.
 
 import("//build/config/ui.gni")
+import("//components/viz/viz.gni")
 
 config("viz_service_implementation") {
 }
 
-component("service") {
+viz_component("service") {
   sources = [
+    "display/display.cc",
+    "display/display.h",
+    "display/display_client.h",
+    "display/display_scheduler.cc",
+    "display/display_scheduler.h",
+    "display/surface_aggregator.cc",
+    "display/surface_aggregator.h",
     "display_embedder/buffer_queue.cc",
     "display_embedder/buffer_queue.h",
     "display_embedder/compositor_overlay_candidate_validator.h",
@@ -23,6 +31,11 @@
     "display_embedder/server_shared_bitmap_manager.h",
     "display_embedder/shared_bitmap_allocation_notifier_impl.cc",
     "display_embedder/shared_bitmap_allocation_notifier_impl.h",
+    "frame_sinks/compositor_frame_sink_support.cc",
+    "frame_sinks/compositor_frame_sink_support.h",
+    "frame_sinks/compositor_frame_sink_support_client.h",
+    "frame_sinks/direct_layer_tree_frame_sink.cc",
+    "frame_sinks/direct_layer_tree_frame_sink.h",
     "frame_sinks/frame_eviction_manager.cc",
     "frame_sinks/frame_eviction_manager.h",
     "frame_sinks/frame_evictor.cc",
@@ -39,7 +52,7 @@
 
   defines = [ "VIZ_SERVICE_IMPLEMENTATION" ]
 
-  configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
+  configs = [ "//build/config/compiler:no_size_t_to_int_warning" ]
 
   deps = [
     "//components/viz/common",
@@ -48,6 +61,8 @@
     # dependency should not be in public_deps.
     "//gpu/ipc/client",
     "//gpu/ipc/service",
+    "//gpu/vulkan:features",
+    "//skia",
     "//ui/display/types",
   ]
 
@@ -58,6 +73,9 @@
     "//cc/surfaces",
     "//gpu/command_buffer/client:gles2_interface",
     "//gpu/ipc:command_buffer",
+    "//ui/gfx",
+    "//ui/gfx/geometry",
+    "//ui/latency",
   ]
 
   if (is_mac) {
@@ -93,19 +111,24 @@
   }
 }
 
-# These are part of the components_unittests build target.
-source_set("unit_tests") {
+viz_source_set("unit_tests") {
   testonly = true
   sources = [
+    "display/display_scheduler_unittest.cc",
+    "display/display_unittest.cc",
+    "display/surface_aggregator_pixeltest.cc",
+    "display/surface_aggregator_unittest.cc",
     "display_embedder/buffer_queue_unittest.cc",
     "display_embedder/server_shared_bitmap_manager_unittest.cc",
+    "frame_sinks/compositor_frame_sink_support_unittest.cc",
+    "frame_sinks/direct_layer_tree_frame_sink_unittest.cc",
   ]
 
   if (!use_aura && !is_mac) {
     sources -= [ "display_embedder/buffer_queue_unittest.cc" ]
   }
 
-  configs += [
+  configs = [
     "//build/config/compiler:no_size_t_to_int_warning",
     "//third_party/khronos:khronos_headers",
   ]
@@ -121,3 +144,19 @@
     "//ui/display/types",
   ]
 }
+
+viz_source_set("perf_tests") {
+  testonly = true
+  sources = [
+    "display/surface_aggregator_perftest.cc",
+  ]
+
+  deps = [
+    ":service",
+    "//base",
+    "//cc:test_support",
+    "//cc/base",
+    "//testing/gtest",
+    "//testing/perf",
+  ]
+}
diff --git a/components/viz/service/DEPS b/components/viz/service/DEPS
new file mode 100644
index 0000000..878bb265
--- /dev/null
+++ b/components/viz/service/DEPS
@@ -0,0 +1,7 @@
+include_rules = [
+  "+cc",
+  "+third_party/skia",
+  "+ui/gfx",
+  "+ui/gfx/geometry",
+  "+ui/latency",
+]
diff --git a/components/viz/service/display/DEPS b/components/viz/service/display/DEPS
new file mode 100644
index 0000000..e8ecaf1
--- /dev/null
+++ b/components/viz/service/display/DEPS
@@ -0,0 +1,24 @@
+include_rules = [
+  "+base",
+  "+cc/base",
+  "+cc/benchmarks",
+  "+cc/output",
+  "+cc/quads",
+  "+cc/resources",
+  "+cc/scheduler",
+  "+cc/surfaces",
+  "+gpu/command_buffer/client",
+  "+gpu/command_buffer/common",
+  "+gpu/vulkan",
+  "+third_party/skia",
+  "+ui/gfx",
+  "+ui/latency",
+]
+
+specific_include_rules = {
+  ".*_(unit|pixel|perf)test\.cc": [
+    "+cc/test",
+    "+components/viz/service/frame_sinks",
+    "+gpu/GLES2",
+  ],
+}
diff --git a/components/viz/service/display/display.cc b/components/viz/service/display/display.cc
new file mode 100644
index 0000000..adffd42
--- /dev/null
+++ b/components/viz/service/display/display.cc
@@ -0,0 +1,434 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/display/display.h"
+
+#include <stddef.h>
+
+#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/timer/elapsed_timer.h"
+#include "base/trace_event/trace_event.h"
+#include "cc/benchmarks/benchmark_instrumentation.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/output/direct_renderer.h"
+#include "cc/output/gl_renderer.h"
+#include "cc/output/renderer_settings.h"
+#include "cc/output/software_renderer.h"
+#include "cc/output/texture_mailbox_deleter.h"
+#include "cc/scheduler/begin_frame_source.h"
+#include "cc/surfaces/surface.h"
+#include "cc/surfaces/surface_manager.h"
+#include "components/viz/service/display/display_client.h"
+#include "components/viz/service/display/display_scheduler.h"
+#include "components/viz/service/display/surface_aggregator.h"
+#include "gpu/command_buffer/client/gles2_interface.h"
+#include "gpu/vulkan/features.h"
+#include "ui/gfx/buffer_types.h"
+
+#if BUILDFLAG(ENABLE_VULKAN)
+#include "cc/output/vulkan_renderer.h"
+#endif
+
+namespace viz {
+
+Display::Display(
+    SharedBitmapManager* bitmap_manager,
+    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
+    const cc::RendererSettings& settings,
+    const FrameSinkId& frame_sink_id,
+    std::unique_ptr<cc::OutputSurface> output_surface,
+    std::unique_ptr<DisplayScheduler> scheduler,
+    std::unique_ptr<cc::TextureMailboxDeleter> texture_mailbox_deleter)
+    : bitmap_manager_(bitmap_manager),
+      gpu_memory_buffer_manager_(gpu_memory_buffer_manager),
+      settings_(settings),
+      frame_sink_id_(frame_sink_id),
+      output_surface_(std::move(output_surface)),
+      scheduler_(std::move(scheduler)),
+      texture_mailbox_deleter_(std::move(texture_mailbox_deleter)) {
+  DCHECK(output_surface_);
+  DCHECK(frame_sink_id_.is_valid());
+  if (scheduler_)
+    scheduler_->SetClient(this);
+}
+
+Display::~Display() {
+  // Only do this if Initialize() happened.
+  if (client_) {
+    if (auto* context = output_surface_->context_provider())
+      context->SetLostContextCallback(base::Closure());
+    if (scheduler_)
+      surface_manager_->RemoveObserver(scheduler_.get());
+  }
+  if (aggregator_) {
+    for (const auto& id_entry : aggregator_->previous_contained_surfaces()) {
+      cc::Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first);
+      if (surface)
+        surface->RunDrawCallback();
+    }
+  }
+}
+
+void Display::Initialize(DisplayClient* client,
+                         cc::SurfaceManager* surface_manager) {
+  DCHECK(client);
+  DCHECK(surface_manager);
+  client_ = client;
+  surface_manager_ = surface_manager;
+  if (scheduler_)
+    surface_manager_->AddObserver(scheduler_.get());
+
+  output_surface_->BindToClient(this);
+  InitializeRenderer();
+
+  if (auto* context = output_surface_->context_provider()) {
+    // This depends on assumptions that Display::Initialize will happen
+    // on the same callstack as the ContextProvider being created/initialized
+    // or else it could miss a callback before setting this.
+    context->SetLostContextCallback(base::Bind(
+        &Display::DidLoseContextProvider,
+        // Unretained is safe since the callback is unset in this class'
+        // destructor and is never posted.
+        base::Unretained(this)));
+  }
+}
+
+void Display::SetLocalSurfaceId(const LocalSurfaceId& id,
+                                float device_scale_factor) {
+  if (current_surface_id_.local_surface_id() == id &&
+      device_scale_factor_ == device_scale_factor) {
+    return;
+  }
+
+  TRACE_EVENT0("viz", "Display::SetSurfaceId");
+  current_surface_id_ = SurfaceId(frame_sink_id_, id);
+  device_scale_factor_ = device_scale_factor;
+
+  UpdateRootSurfaceResourcesLocked();
+  if (scheduler_)
+    scheduler_->SetNewRootSurface(current_surface_id_);
+}
+
+void Display::SetVisible(bool visible) {
+  TRACE_EVENT1("viz", "Display::SetVisible", "visible", visible);
+  if (renderer_)
+    renderer_->SetVisible(visible);
+  if (scheduler_)
+    scheduler_->SetVisible(visible);
+  visible_ = visible;
+
+  if (!visible) {
+    // Damage tracker needs a full reset as renderer resources are dropped when
+    // not visible.
+    if (aggregator_ && current_surface_id_.is_valid())
+      aggregator_->SetFullDamageForSurface(current_surface_id_);
+  }
+}
+
+void Display::Resize(const gfx::Size& size) {
+  if (size == current_surface_size_)
+    return;
+
+  TRACE_EVENT0("viz", "Display::Resize");
+
+  // Need to ensure all pending swaps have executed before the window is
+  // resized, or D3D11 will scale the swap output.
+  if (settings_.finish_rendering_on_resize) {
+    if (!swapped_since_resize_ && scheduler_)
+      scheduler_->ForceImmediateSwapIfPossible();
+    if (swapped_since_resize_ && output_surface_ &&
+        output_surface_->context_provider())
+      output_surface_->context_provider()->ContextGL()->ShallowFinishCHROMIUM();
+  }
+  swapped_since_resize_ = false;
+  current_surface_size_ = size;
+  if (scheduler_)
+    scheduler_->DisplayResized();
+}
+
+void Display::SetColorSpace(const gfx::ColorSpace& blending_color_space,
+                            const gfx::ColorSpace& device_color_space) {
+  blending_color_space_ = blending_color_space;
+  device_color_space_ = device_color_space;
+  if (aggregator_) {
+    aggregator_->SetOutputColorSpace(blending_color_space, device_color_space_);
+  }
+}
+
+void Display::SetOutputIsSecure(bool secure) {
+  if (secure == output_is_secure_)
+    return;
+  output_is_secure_ = secure;
+
+  if (aggregator_) {
+    aggregator_->set_output_is_secure(secure);
+    // Force a redraw.
+    if (current_surface_id_.is_valid())
+      aggregator_->SetFullDamageForSurface(current_surface_id_);
+  }
+}
+
+void Display::InitializeRenderer() {
+  // Not relevant for display compositor since it's not delegated.
+  constexpr bool delegated_sync_points_required = false;
+  resource_provider_ = base::MakeUnique<cc::ResourceProvider>(
+      output_surface_->context_provider(), bitmap_manager_,
+      gpu_memory_buffer_manager_, nullptr, delegated_sync_points_required,
+      settings_.enable_color_correct_rendering, settings_.resource_settings);
+
+  if (output_surface_->context_provider()) {
+    DCHECK(texture_mailbox_deleter_);
+    renderer_ = base::MakeUnique<cc::GLRenderer>(
+        &settings_, output_surface_.get(), resource_provider_.get(),
+        texture_mailbox_deleter_.get());
+  } else if (output_surface_->vulkan_context_provider()) {
+#if defined(ENABLE_VULKAN)
+    DCHECK(texture_mailbox_deleter_);
+    renderer_ = base::MakeUnique<cc::VulkanRenderer>(
+        &settings_, output_surface_.get(), resource_provider_.get(),
+        texture_mailbox_deleter_.get(), settings_.highp_threshold_min);
+#else
+    NOTREACHED();
+#endif
+  } else {
+    auto renderer = base::MakeUnique<cc::SoftwareRenderer>(
+        &settings_, output_surface_.get(), resource_provider_.get());
+    software_renderer_ = renderer.get();
+    renderer_ = std::move(renderer);
+  }
+
+  renderer_->Initialize();
+  renderer_->SetVisible(visible_);
+
+  // TODO(jbauman): Outputting an incomplete quad list doesn't work when using
+  // overlays.
+  bool output_partial_list = renderer_->use_partial_swap() &&
+                             !output_surface_->GetOverlayCandidateValidator();
+  aggregator_.reset(new SurfaceAggregator(
+      surface_manager_, resource_provider_.get(), output_partial_list));
+  aggregator_->set_output_is_secure(output_is_secure_);
+  aggregator_->SetOutputColorSpace(blending_color_space_, device_color_space_);
+}
+
+void Display::UpdateRootSurfaceResourcesLocked() {
+  cc::Surface* surface = surface_manager_->GetSurfaceForId(current_surface_id_);
+  bool root_surface_resources_locked = !surface || !surface->HasActiveFrame();
+  if (scheduler_)
+    scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked);
+}
+
+void Display::DidLoseContextProvider() {
+  if (scheduler_)
+    scheduler_->OutputSurfaceLost();
+  // WARNING: The client may delete the Display in this method call. Do not
+  // make any additional references to members after this call.
+  client_->DisplayOutputSurfaceLost();
+}
+
+bool Display::DrawAndSwap() {
+  TRACE_EVENT0("viz", "Display::DrawAndSwap");
+
+  if (!current_surface_id_.is_valid()) {
+    TRACE_EVENT_INSTANT0("viz", "No root surface.", TRACE_EVENT_SCOPE_THREAD);
+    return false;
+  }
+
+  if (!output_surface_) {
+    TRACE_EVENT_INSTANT0("viz", "No output surface", TRACE_EVENT_SCOPE_THREAD);
+    return false;
+  }
+
+  base::ElapsedTimer aggregate_timer;
+  cc::CompositorFrame frame = aggregator_->Aggregate(current_surface_id_);
+  UMA_HISTOGRAM_COUNTS_1M("Compositing.SurfaceAggregator.AggregateUs",
+                          aggregate_timer.Elapsed().InMicroseconds());
+
+  if (frame.render_pass_list.empty()) {
+    TRACE_EVENT_INSTANT0("viz", "Empty aggregated frame.",
+                         TRACE_EVENT_SCOPE_THREAD);
+    return false;
+  }
+
+  // Run callbacks early to allow pipelining.
+  for (const auto& id_entry : aggregator_->previous_contained_surfaces()) {
+    cc::Surface* surface = surface_manager_->GetSurfaceForId(id_entry.first);
+    if (surface)
+      surface->RunDrawCallback();
+  }
+
+  frame.metadata.latency_info.insert(frame.metadata.latency_info.end(),
+                                     stored_latency_info_.begin(),
+                                     stored_latency_info_.end());
+  stored_latency_info_.clear();
+  bool have_copy_requests = false;
+  for (const auto& pass : frame.render_pass_list) {
+    have_copy_requests |= !pass->copy_requests.empty();
+  }
+
+  gfx::Size surface_size;
+  bool have_damage = false;
+  auto& last_render_pass = *frame.render_pass_list.back();
+  if (last_render_pass.output_rect.size() != current_surface_size_ &&
+      last_render_pass.damage_rect == last_render_pass.output_rect &&
+      !current_surface_size_.IsEmpty()) {
+    // Resize the output rect to the current surface size so that we won't
+    // skip the draw and so that the GL swap won't stretch the output.
+    last_render_pass.output_rect.set_size(current_surface_size_);
+    last_render_pass.damage_rect = last_render_pass.output_rect;
+  }
+  surface_size = last_render_pass.output_rect.size();
+  have_damage = !last_render_pass.damage_rect.size().IsEmpty();
+
+  bool size_matches = surface_size == current_surface_size_;
+  if (!size_matches)
+    TRACE_EVENT_INSTANT0("viz", "Size mismatch.", TRACE_EVENT_SCOPE_THREAD);
+
+  bool should_draw = have_copy_requests || (have_damage && size_matches);
+
+  // If the surface is suspended then the resources to be used by the draw are
+  // likely destroyed.
+  if (output_surface_->SurfaceIsSuspendForRecycle()) {
+    TRACE_EVENT_INSTANT0("viz", "Surface is suspended for recycle.",
+                         TRACE_EVENT_SCOPE_THREAD);
+    should_draw = false;
+  }
+
+  client_->DisplayWillDrawAndSwap(should_draw, frame.render_pass_list);
+
+  if (should_draw) {
+    bool disable_image_filtering =
+        frame.metadata.is_resourceless_software_draw_with_scroll_or_animation;
+    if (software_renderer_) {
+      software_renderer_->SetDisablePictureQuadImageFiltering(
+          disable_image_filtering);
+    } else {
+      // This should only be set for software draws in synchronous compositor.
+      DCHECK(!disable_image_filtering);
+    }
+
+    base::ElapsedTimer draw_timer;
+    renderer_->DecideRenderPassAllocationsForFrame(frame.render_pass_list);
+    renderer_->DrawFrame(&frame.render_pass_list, device_scale_factor_,
+                         current_surface_size_);
+    if (software_renderer_) {
+      UMA_HISTOGRAM_COUNTS_1M("Compositing.DirectRenderer.Software.DrawFrameUs",
+                              draw_timer.Elapsed().InMicroseconds());
+    } else {
+      UMA_HISTOGRAM_COUNTS_1M("Compositing.DirectRenderer.GL.DrawFrameUs",
+                              draw_timer.Elapsed().InMicroseconds());
+    }
+  } else {
+    TRACE_EVENT_INSTANT0("viz", "Draw skipped.", TRACE_EVENT_SCOPE_THREAD);
+  }
+
+  bool should_swap = should_draw && size_matches;
+  if (should_swap) {
+    swapped_since_resize_ = true;
+    for (auto& latency : frame.metadata.latency_info) {
+      TRACE_EVENT_WITH_FLOW1(
+          "input,benchmark", "LatencyInfo.Flow",
+          TRACE_ID_DONT_MANGLE(latency.trace_id()),
+          TRACE_EVENT_FLAG_FLOW_IN | TRACE_EVENT_FLAG_FLOW_OUT, "step",
+          "Display::DrawAndSwap");
+    }
+    cc::benchmark_instrumentation::IssueDisplayRenderingStatsEvent();
+    renderer_->SwapBuffers(std::move(frame.metadata.latency_info));
+    if (scheduler_)
+      scheduler_->DidSwapBuffers();
+  } else {
+    if (have_damage && !size_matches)
+      aggregator_->SetFullDamageForSurface(current_surface_id_);
+    TRACE_EVENT_INSTANT0("viz", "Swap skipped.", TRACE_EVENT_SCOPE_THREAD);
+
+    // Do not store more that the allowed size.
+    if (ui::LatencyInfo::Verify(frame.metadata.latency_info,
+                                "Display::DrawAndSwap")) {
+      stored_latency_info_.insert(stored_latency_info_.end(),
+                                  frame.metadata.latency_info.begin(),
+                                  frame.metadata.latency_info.end());
+    }
+
+    if (scheduler_) {
+      scheduler_->DidSwapBuffers();
+      scheduler_->DidReceiveSwapBuffersAck();
+    }
+  }
+
+  client_->DisplayDidDrawAndSwap();
+  return true;
+}
+
+void Display::DidReceiveSwapBuffersAck() {
+  if (scheduler_)
+    scheduler_->DidReceiveSwapBuffersAck();
+  if (renderer_)
+    renderer_->SwapBuffersComplete();
+}
+
+void Display::DidReceiveTextureInUseResponses(
+    const gpu::TextureInUseResponses& responses) {
+  if (renderer_)
+    renderer_->DidReceiveTextureInUseResponses(responses);
+}
+
+void Display::SetNeedsRedrawRect(const gfx::Rect& damage_rect) {
+  aggregator_->SetFullDamageForSurface(current_surface_id_);
+  if (scheduler_) {
+    cc::BeginFrameAck ack;
+    ack.has_damage = true;
+    scheduler_->ProcessSurfaceDamage(current_surface_id_, ack, true);
+  }
+}
+
+bool Display::SurfaceDamaged(const SurfaceId& surface_id,
+                             const cc::BeginFrameAck& ack) {
+  bool display_damaged = false;
+  if (ack.has_damage) {
+    if (aggregator_ &&
+        aggregator_->previous_contained_surfaces().count(surface_id)) {
+      cc::Surface* surface = surface_manager_->GetSurfaceForId(surface_id);
+      if (surface) {
+        DCHECK(surface->HasActiveFrame());
+        if (surface->GetActiveFrame().resource_list.empty())
+          aggregator_->ReleaseResources(surface_id);
+      }
+      display_damaged = true;
+      if (surface_id == current_surface_id_)
+        UpdateRootSurfaceResourcesLocked();
+    } else if (surface_id == current_surface_id_) {
+      display_damaged = true;
+      UpdateRootSurfaceResourcesLocked();
+    }
+  }
+
+  return display_damaged;
+}
+
+void Display::SurfaceDiscarded(const SurfaceId& surface_id) {
+  if (aggregator_)
+    aggregator_->ReleaseResources(surface_id);
+}
+
+bool Display::SurfaceHasUndrawnFrame(const SurfaceId& surface_id) const {
+  if (!surface_manager_)
+    return false;
+
+  cc::Surface* surface = surface_manager_->GetSurfaceForId(surface_id);
+  if (!surface)
+    return false;
+
+  return surface->HasUndrawnActiveFrame();
+}
+
+const SurfaceId& Display::CurrentSurfaceId() {
+  return current_surface_id_;
+}
+
+void Display::ForceImmediateDrawAndSwapIfPossible() {
+  if (scheduler_)
+    scheduler_->ForceImmediateSwapIfPossible();
+}
+
+}  // namespace viz
diff --git a/components/viz/service/display/display.h b/components/viz/service/display/display.h
new file mode 100644
index 0000000..18b5302
--- /dev/null
+++ b/components/viz/service/display/display.h
@@ -0,0 +1,135 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_H_
+
+#include <memory>
+#include <vector>
+
+#include "base/macros.h"
+#include "cc/output/output_surface_client.h"
+#include "cc/resources/returned_resource.h"
+#include "cc/scheduler/begin_frame_source.h"
+#include "cc/surfaces/surface_manager.h"
+#include "components/viz/common/frame_sink_id.h"
+#include "components/viz/common/surface_id.h"
+#include "components/viz/service/display/display_scheduler.h"
+#include "components/viz/service/display/surface_aggregator.h"
+#include "components/viz/service/viz_service_export.h"
+#include "gpu/command_buffer/common/texture_in_use_response.h"
+#include "ui/gfx/color_space.h"
+#include "ui/latency/latency_info.h"
+
+namespace cc {
+class DirectRenderer;
+class OutputSurface;
+class RendererSettings;
+class ResourceProvider;
+class SoftwareRenderer;
+class TextureMailboxDeleter;
+}  // namespace cc
+
+namespace gpu {
+class GpuMemoryBufferManager;
+}
+
+namespace gfx {
+class Size;
+}
+
+namespace viz {
+
+class DisplayClient;
+class SharedBitmapManager;
+
+// A Display produces a surface that can be used to draw to a physical display
+// (OutputSurface). The client is responsible for creating and sizing the
+// surface IDs used to draw into the display and deciding when to draw.
+class VIZ_SERVICE_EXPORT Display : public DisplaySchedulerClient,
+                                   public cc::OutputSurfaceClient {
+ public:
+  // The |begin_frame_source| and |scheduler| may be null (together). In that
+  // case, DrawAndSwap must be called externally when needed.
+  Display(SharedBitmapManager* bitmap_manager,
+          gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
+          const cc::RendererSettings& settings,
+          const FrameSinkId& frame_sink_id,
+          std::unique_ptr<cc::OutputSurface> output_surface,
+          std::unique_ptr<DisplayScheduler> scheduler,
+          std::unique_ptr<cc::TextureMailboxDeleter> texture_mailbox_deleter);
+
+  ~Display() override;
+
+  void Initialize(DisplayClient* client, cc::SurfaceManager* surface_manager);
+
+  // device_scale_factor is used to communicate to the external window system
+  // what scale this was rendered at.
+  void SetLocalSurfaceId(const LocalSurfaceId& id, float device_scale_factor);
+  void SetVisible(bool visible);
+  void Resize(const gfx::Size& new_size);
+  void SetColorSpace(const gfx::ColorSpace& blending_color_space,
+                     const gfx::ColorSpace& device_color_space);
+  void SetOutputIsSecure(bool secure);
+
+  const SurfaceId& CurrentSurfaceId();
+
+  // DisplaySchedulerClient implementation.
+  bool DrawAndSwap() override;
+  bool SurfaceHasUndrawnFrame(const SurfaceId& surface_id) const override;
+  bool SurfaceDamaged(const SurfaceId& surface_id,
+                      const cc::BeginFrameAck& ack) override;
+  void SurfaceDiscarded(const SurfaceId& surface_id) override;
+
+  // OutputSurfaceClient implementation.
+  void SetNeedsRedrawRect(const gfx::Rect& damage_rect) override;
+  void DidReceiveSwapBuffersAck() override;
+  void DidReceiveTextureInUseResponses(
+      const gpu::TextureInUseResponses& responses) override;
+
+  bool has_scheduler() const { return !!scheduler_; }
+  cc::DirectRenderer* renderer_for_testing() const { return renderer_.get(); }
+  size_t stored_latency_info_size_for_testing() const {
+    return stored_latency_info_.size();
+  }
+
+  void ForceImmediateDrawAndSwapIfPossible();
+
+ private:
+  void InitializeRenderer();
+  void UpdateRootSurfaceResourcesLocked();
+  void DidLoseContextProvider();
+
+  SharedBitmapManager* const bitmap_manager_;
+  gpu::GpuMemoryBufferManager* const gpu_memory_buffer_manager_;
+  const cc::RendererSettings settings_;
+
+  DisplayClient* client_ = nullptr;
+  cc::SurfaceManager* surface_manager_ = nullptr;
+  const FrameSinkId frame_sink_id_;
+  SurfaceId current_surface_id_;
+  gfx::Size current_surface_size_;
+  float device_scale_factor_ = 1.f;
+  gfx::ColorSpace blending_color_space_ = gfx::ColorSpace::CreateSRGB();
+  gfx::ColorSpace device_color_space_ = gfx::ColorSpace::CreateSRGB();
+  bool visible_ = false;
+  bool swapped_since_resize_ = false;
+  bool output_is_secure_ = false;
+
+  std::unique_ptr<cc::OutputSurface> output_surface_;
+  std::unique_ptr<DisplayScheduler> scheduler_;
+  std::unique_ptr<cc::ResourceProvider> resource_provider_;
+  std::unique_ptr<SurfaceAggregator> aggregator_;
+  std::unique_ptr<cc::TextureMailboxDeleter> texture_mailbox_deleter_;
+  std::unique_ptr<cc::DirectRenderer> renderer_;
+  cc::SoftwareRenderer* software_renderer_ = nullptr;
+  std::vector<ui::LatencyInfo> stored_latency_info_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(Display);
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_H_
diff --git a/components/viz/service/display/display_client.h b/components/viz/service/display/display_client.h
new file mode 100644
index 0000000..b22a693
--- /dev/null
+++ b/components/viz/service/display/display_client.h
@@ -0,0 +1,24 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_CLIENT_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_CLIENT_H_
+
+#include "cc/quads/render_pass.h"
+
+namespace viz {
+
+class DisplayClient {
+ public:
+  virtual ~DisplayClient() {}
+  virtual void DisplayOutputSurfaceLost() = 0;
+  virtual void DisplayWillDrawAndSwap(
+      bool will_draw_and_swap,
+      const cc::RenderPassList& render_passes) = 0;
+  virtual void DisplayDidDrawAndSwap() = 0;
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_CLIENT_H_
diff --git a/components/viz/service/display/display_scheduler.cc b/components/viz/service/display/display_scheduler.cc
new file mode 100644
index 0000000..d7a0c9f
--- /dev/null
+++ b/components/viz/service/display/display_scheduler.cc
@@ -0,0 +1,492 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/display/display_scheduler.h"
+
+#include <vector>
+
+#include "base/auto_reset.h"
+#include "base/stl_util.h"
+#include "base/trace_event/trace_event.h"
+#include "cc/output/output_surface.h"
+#include "cc/surfaces/surface_info.h"
+
+namespace viz {
+
+DisplayScheduler::DisplayScheduler(cc::BeginFrameSource* begin_frame_source,
+                                   base::SingleThreadTaskRunner* task_runner,
+                                   int max_pending_swaps,
+                                   bool wait_for_all_surfaces_before_draw)
+    : client_(nullptr),
+      begin_frame_source_(begin_frame_source),
+      task_runner_(task_runner),
+      inside_surface_damaged_(false),
+      visible_(false),
+      output_surface_lost_(false),
+      root_surface_resources_locked_(true),
+      inside_begin_frame_deadline_interval_(false),
+      needs_draw_(false),
+      expecting_root_surface_damage_because_of_resize_(false),
+      has_pending_surfaces_(false),
+      next_swap_id_(1),
+      pending_swaps_(0),
+      max_pending_swaps_(max_pending_swaps),
+      wait_for_all_surfaces_before_draw_(wait_for_all_surfaces_before_draw),
+      observing_begin_frame_source_(false),
+      weak_ptr_factory_(this) {
+  begin_frame_deadline_closure_ = base::Bind(
+      &DisplayScheduler::OnBeginFrameDeadline, weak_ptr_factory_.GetWeakPtr());
+}
+
+DisplayScheduler::~DisplayScheduler() {
+  StopObservingBeginFrames();
+}
+
+void DisplayScheduler::SetClient(DisplaySchedulerClient* client) {
+  client_ = client;
+}
+
+void DisplayScheduler::SetVisible(bool visible) {
+  if (visible_ == visible)
+    return;
+
+  visible_ = visible;
+  // If going invisible, we'll stop observing begin frames once we try
+  // to draw and fail.
+  StartObservingBeginFrames();
+  ScheduleBeginFrameDeadline();
+}
+
+// If we try to draw when the root surface resources are locked, the
+// draw will fail.
+void DisplayScheduler::SetRootSurfaceResourcesLocked(bool locked) {
+  TRACE_EVENT1("viz", "DisplayScheduler::SetRootSurfaceResourcesLocked",
+               "locked", locked);
+  root_surface_resources_locked_ = locked;
+  ScheduleBeginFrameDeadline();
+}
+
+// This is used to force an immediate swap before a resize.
+void DisplayScheduler::ForceImmediateSwapIfPossible() {
+  TRACE_EVENT0("viz", "DisplayScheduler::ForceImmediateSwapIfPossible");
+  bool in_begin = inside_begin_frame_deadline_interval_;
+  bool did_draw = AttemptDrawAndSwap();
+  if (in_begin)
+    DidFinishFrame(did_draw);
+}
+
+void DisplayScheduler::DisplayResized() {
+  expecting_root_surface_damage_because_of_resize_ = true;
+  needs_draw_ = true;
+  ScheduleBeginFrameDeadline();
+}
+
+// Notification that there was a resize or the root surface changed and
+// that we should just draw immediately.
+void DisplayScheduler::SetNewRootSurface(const SurfaceId& root_surface_id) {
+  TRACE_EVENT0("viz", "DisplayScheduler::SetNewRootSurface");
+  root_surface_id_ = root_surface_id;
+  cc::BeginFrameAck ack;
+  ack.has_damage = true;
+  ProcessSurfaceDamage(root_surface_id, ack, true);
+}
+
+// Indicates that there was damage to one of the surfaces.
+// Has some logic to wait for multiple active surfaces before
+// triggering the deadline.
+void DisplayScheduler::ProcessSurfaceDamage(const SurfaceId& surface_id,
+                                            const cc::BeginFrameAck& ack,
+                                            bool display_damaged) {
+  TRACE_EVENT1("viz", "DisplayScheduler::SurfaceDamaged", "surface_id",
+               surface_id.ToString());
+
+  // We may cause a new BeginFrame to be run inside this method, but to help
+  // avoid being reentrant to the caller of SurfaceDamaged, track when this is
+  // happening with |inside_surface_damaged_|.
+  base::AutoReset<bool> auto_reset(&inside_surface_damaged_, true);
+
+  if (display_damaged) {
+    needs_draw_ = true;
+
+    if (surface_id == root_surface_id_)
+      expecting_root_surface_damage_because_of_resize_ = false;
+
+    StartObservingBeginFrames();
+  }
+
+  // Update surface state.
+  bool valid_ack =
+      ack.sequence_number != cc::BeginFrameArgs::kInvalidFrameNumber;
+  if (valid_ack) {
+    auto it = surface_states_.find(surface_id);
+    if (it != surface_states_.end())
+      it->second.last_ack = ack;
+    else
+      valid_ack = false;
+  }
+
+  bool pending_surfaces_changed = false;
+  if (display_damaged || valid_ack)
+    pending_surfaces_changed = UpdateHasPendingSurfaces();
+
+  if (display_damaged || pending_surfaces_changed)
+    ScheduleBeginFrameDeadline();
+}
+
+bool DisplayScheduler::UpdateHasPendingSurfaces() {
+  // If we're not currently inside a deadline interval, we will call
+  // UpdateHasPendingSurfaces() again during OnBeginFrameImpl().
+  if (!inside_begin_frame_deadline_interval_ || !client_)
+    return false;
+
+  bool old_value = has_pending_surfaces_;
+
+  for (const std::pair<SurfaceId, SurfaceBeginFrameState>& entry :
+       surface_states_) {
+    const SurfaceId& surface_id = entry.first;
+    const SurfaceBeginFrameState& state = entry.second;
+
+    // Surface is ready if it hasn't received the current BeginFrame or receives
+    // BeginFrames from a different source and thus likely belongs to a
+    // different surface hierarchy.
+    uint32_t source_id = current_begin_frame_args_.source_id;
+    uint64_t sequence_number = current_begin_frame_args_.sequence_number;
+    if (!state.last_args.IsValid() || state.last_args.source_id != source_id ||
+        state.last_args.sequence_number != sequence_number) {
+      continue;
+    }
+
+    // Surface is ready if it has acknowledged the current BeginFrame.
+    if (state.last_ack.source_id == source_id &&
+        state.last_ack.sequence_number == sequence_number) {
+      continue;
+    }
+
+    // Surface is ready if there is an undrawn active CompositorFrame, because
+    // its producer is CompositorFrameAck throttled.
+    if (client_->SurfaceHasUndrawnFrame(entry.first))
+      continue;
+
+    has_pending_surfaces_ = true;
+    TRACE_EVENT_INSTANT2("viz", "DisplayScheduler::UpdateHasPendingSurfaces",
+                         TRACE_EVENT_SCOPE_THREAD, "has_pending_surfaces",
+                         has_pending_surfaces_, "pending_surface_id",
+                         surface_id.ToString());
+    return has_pending_surfaces_ != old_value;
+  }
+  has_pending_surfaces_ = false;
+  TRACE_EVENT_INSTANT1("viz", "DisplayScheduler::UpdateHasPendingSurfaces",
+                       TRACE_EVENT_SCOPE_THREAD, "has_pending_surfaces",
+                       has_pending_surfaces_);
+  return has_pending_surfaces_ != old_value;
+}
+
+void DisplayScheduler::OutputSurfaceLost() {
+  TRACE_EVENT0("viz", "DisplayScheduler::OutputSurfaceLost");
+  output_surface_lost_ = true;
+  ScheduleBeginFrameDeadline();
+}
+
+bool DisplayScheduler::DrawAndSwap() {
+  TRACE_EVENT0("viz", "DisplayScheduler::DrawAndSwap");
+  DCHECK_LT(pending_swaps_, max_pending_swaps_);
+  DCHECK(!output_surface_lost_);
+
+  bool success = client_->DrawAndSwap();
+  if (!success)
+    return false;
+
+  needs_draw_ = false;
+  return true;
+}
+
+bool DisplayScheduler::OnBeginFrameDerivedImpl(const cc::BeginFrameArgs& args) {
+  base::TimeTicks now = base::TimeTicks::Now();
+  TRACE_EVENT2("viz", "DisplayScheduler::BeginFrame", "args", args.AsValue(),
+               "now", now);
+
+  if (inside_surface_damaged_) {
+    // Repost this so that we don't run a missed BeginFrame on the same
+    // callstack. Otherwise we end up running unexpected scheduler actions
+    // immediately while inside some other action (such as submitting a
+    // CompositorFrame for a SurfaceFactory).
+    DCHECK_EQ(args.type, cc::BeginFrameArgs::MISSED);
+    DCHECK(missed_begin_frame_task_.IsCancelled());
+    missed_begin_frame_task_.Reset(base::Bind(
+        base::IgnoreResult(&DisplayScheduler::OnBeginFrameDerivedImpl),
+        // The CancelableCallback will not run after it is destroyed, which
+        // happens when |this| is destroyed.
+        base::Unretained(this), args));
+    task_runner_->PostTask(FROM_HERE, missed_begin_frame_task_.callback());
+    return true;
+  }
+
+  // Save the |BeginFrameArgs| as the callback (missed_begin_frame_task_) can be
+  // destroyed if we StopObservingBeginFrames(), and it would take the |args|
+  // with it. Instead save the args and cancel the |missed_begin_frame_task_|.
+  cc::BeginFrameArgs save_args = args;
+  // If we get another BeginFrame before a posted missed frame, just drop the
+  // missed frame. Also if this was the missed frame, drop the Callback inside
+  // it.
+  missed_begin_frame_task_.Cancel();
+
+  // If we get another BeginFrame before the previous deadline,
+  // synchronously trigger the previous deadline before progressing.
+  if (inside_begin_frame_deadline_interval_)
+    OnBeginFrameDeadline();
+
+  // Schedule the deadline.
+  current_begin_frame_args_ = save_args;
+  current_begin_frame_args_.deadline -=
+      cc::BeginFrameArgs::DefaultEstimatedParentDrawTime();
+  inside_begin_frame_deadline_interval_ = true;
+  UpdateHasPendingSurfaces();
+  ScheduleBeginFrameDeadline();
+
+  return true;
+}
+
+void DisplayScheduler::StartObservingBeginFrames() {
+  if (!observing_begin_frame_source_ && ShouldDraw()) {
+    begin_frame_source_->AddObserver(this);
+    observing_begin_frame_source_ = true;
+  }
+}
+
+void DisplayScheduler::StopObservingBeginFrames() {
+  if (observing_begin_frame_source_) {
+    begin_frame_source_->RemoveObserver(this);
+    observing_begin_frame_source_ = false;
+
+    // A missed BeginFrame may be queued, so drop that too if we're going to
+    // stop listening.
+    missed_begin_frame_task_.Cancel();
+  }
+}
+
+bool DisplayScheduler::ShouldDraw() {
+  // Note: When any of these cases becomes true, StartObservingBeginFrames must
+  // be called to ensure the draw will happen.
+  return needs_draw_ && !output_surface_lost_ && visible_;
+}
+
+void DisplayScheduler::OnBeginFrameSourcePausedChanged(bool paused) {
+  // BeginFrameSources used with DisplayScheduler do not make use of this
+  // feature.
+  if (paused)
+    NOTIMPLEMENTED();
+}
+
+void DisplayScheduler::OnSurfaceCreated(const cc::SurfaceInfo& surface_info) {}
+
+void DisplayScheduler::OnSurfaceDestroyed(const SurfaceId& surface_id) {
+  auto it = surface_states_.find(surface_id);
+  if (it == surface_states_.end())
+    return;
+  surface_states_.erase(it);
+  if (UpdateHasPendingSurfaces())
+    ScheduleBeginFrameDeadline();
+}
+
+bool DisplayScheduler::OnSurfaceDamaged(const SurfaceId& surface_id,
+                                        const cc::BeginFrameAck& ack) {
+  bool damaged = client_->SurfaceDamaged(surface_id, ack);
+  ProcessSurfaceDamage(surface_id, ack, damaged);
+
+  return damaged;
+}
+
+void DisplayScheduler::OnSurfaceDiscarded(const SurfaceId& surface_id) {
+  client_->SurfaceDiscarded(surface_id);
+}
+
+void DisplayScheduler::OnSurfaceDamageExpected(const SurfaceId& surface_id,
+                                               const cc::BeginFrameArgs& args) {
+  TRACE_EVENT1("viz", "DisplayScheduler::SurfaceDamageExpected", "surface_id",
+               surface_id.ToString());
+  // Insert a new state for the surface if we don't know of it yet. We don't use
+  // OnSurfaceCreated for this, because it may not be called if a
+  // CompositorFrameSinkSupport starts submitting frames to a different Display,
+  // but continues using the same Surface, or if a Surface does not activate its
+  // first CompositorFrame immediately.
+  surface_states_[surface_id].last_args = args;
+  if (UpdateHasPendingSurfaces())
+    ScheduleBeginFrameDeadline();
+}
+
+void DisplayScheduler::OnSurfaceWillDraw(const SurfaceId& surface_id) {}
+
+base::TimeTicks DisplayScheduler::DesiredBeginFrameDeadlineTime() const {
+  switch (AdjustedBeginFrameDeadlineMode()) {
+    case BeginFrameDeadlineMode::kImmediate:
+      return base::TimeTicks();
+    case BeginFrameDeadlineMode::kRegular:
+      return current_begin_frame_args_.deadline;
+    case BeginFrameDeadlineMode::kLate:
+      return current_begin_frame_args_.frame_time +
+             current_begin_frame_args_.interval;
+    case BeginFrameDeadlineMode::kNone:
+      return base::TimeTicks::Max();
+    default:
+      NOTREACHED();
+      return base::TimeTicks();
+  }
+}
+
+DisplayScheduler::BeginFrameDeadlineMode
+DisplayScheduler::AdjustedBeginFrameDeadlineMode() const {
+  BeginFrameDeadlineMode mode = DesiredBeginFrameDeadlineMode();
+
+  // In blocking mode, late and regular deadline should not apply. Wait
+  // indefinitely instead.
+  if (wait_for_all_surfaces_before_draw_ &&
+      (mode == BeginFrameDeadlineMode::kRegular ||
+       mode == BeginFrameDeadlineMode::kLate)) {
+    return BeginFrameDeadlineMode::kNone;
+  }
+
+  return mode;
+}
+
+DisplayScheduler::BeginFrameDeadlineMode
+DisplayScheduler::DesiredBeginFrameDeadlineMode() const {
+  if (output_surface_lost_) {
+    TRACE_EVENT_INSTANT0("viz", "Lost output surface",
+                         TRACE_EVENT_SCOPE_THREAD);
+    return BeginFrameDeadlineMode::kImmediate;
+  }
+
+  if (pending_swaps_ >= max_pending_swaps_) {
+    TRACE_EVENT_INSTANT0("viz", "Swap throttled", TRACE_EVENT_SCOPE_THREAD);
+    return BeginFrameDeadlineMode::kLate;
+  }
+
+  if (root_surface_resources_locked_) {
+    TRACE_EVENT_INSTANT0("viz", "Root surface resources locked",
+                         TRACE_EVENT_SCOPE_THREAD);
+    return BeginFrameDeadlineMode::kLate;
+  }
+
+  bool all_surfaces_ready = !has_pending_surfaces_ &&
+                            root_surface_id_.is_valid() &&
+                            !expecting_root_surface_damage_because_of_resize_;
+
+  // When no draw is needed, only allow an early deadline in full-pipe mode.
+  // This way, we can unblock the BeginFrame in full-pipe mode if no draw is
+  // necessary, but accommodate damage as a result of missed BeginFrames from
+  // clients otherwise.
+  bool allow_early_deadline_without_draw = wait_for_all_surfaces_before_draw_;
+
+  if (all_surfaces_ready &&
+      (needs_draw_ || allow_early_deadline_without_draw)) {
+    TRACE_EVENT_INSTANT0("viz", "All active surfaces ready",
+                         TRACE_EVENT_SCOPE_THREAD);
+    return BeginFrameDeadlineMode::kImmediate;
+  }
+
+  if (!needs_draw_) {
+    TRACE_EVENT_INSTANT0("cc", "No damage yet", TRACE_EVENT_SCOPE_THREAD);
+    return BeginFrameDeadlineMode::kLate;
+  }
+
+  // TODO(mithro): Be smarter about resize deadlines.
+  if (expecting_root_surface_damage_because_of_resize_) {
+    TRACE_EVENT_INSTANT0("viz", "Entire display damaged",
+                         TRACE_EVENT_SCOPE_THREAD);
+    return BeginFrameDeadlineMode::kLate;
+  }
+
+  TRACE_EVENT_INSTANT0("viz", "More damage expected soon",
+                       TRACE_EVENT_SCOPE_THREAD);
+  return BeginFrameDeadlineMode::kRegular;
+}
+
+void DisplayScheduler::ScheduleBeginFrameDeadline() {
+  TRACE_EVENT0("viz", "DisplayScheduler::ScheduleBeginFrameDeadline");
+
+  // We need to wait for the next BeginFrame before scheduling a deadline.
+  if (!inside_begin_frame_deadline_interval_) {
+    TRACE_EVENT_INSTANT0("viz", "Waiting for next BeginFrame",
+                         TRACE_EVENT_SCOPE_THREAD);
+    DCHECK(begin_frame_deadline_task_.IsCancelled());
+    return;
+  }
+
+  // Determine the deadline we want to use.
+  base::TimeTicks desired_deadline = DesiredBeginFrameDeadlineTime();
+
+  // Avoid re-scheduling the deadline if it's already correctly scheduled.
+  if (!begin_frame_deadline_task_.IsCancelled() &&
+      desired_deadline == begin_frame_deadline_task_time_) {
+    TRACE_EVENT_INSTANT0("viz", "Using existing deadline",
+                         TRACE_EVENT_SCOPE_THREAD);
+    return;
+  }
+
+  // Schedule the deadline.
+  begin_frame_deadline_task_time_ = desired_deadline;
+  begin_frame_deadline_task_.Cancel();
+
+  if (begin_frame_deadline_task_time_ == base::TimeTicks::Max()) {
+    TRACE_EVENT_INSTANT0("cc", "Using infinite deadline",
+                         TRACE_EVENT_SCOPE_THREAD);
+    return;
+  }
+
+  begin_frame_deadline_task_.Reset(begin_frame_deadline_closure_);
+  base::TimeDelta delta =
+      std::max(base::TimeDelta(), desired_deadline - base::TimeTicks::Now());
+  task_runner_->PostDelayedTask(FROM_HERE,
+                                begin_frame_deadline_task_.callback(), delta);
+  TRACE_EVENT2("viz", "Using new deadline", "delta", delta.ToInternalValue(),
+               "desired_deadline", desired_deadline);
+}
+
+bool DisplayScheduler::AttemptDrawAndSwap() {
+  inside_begin_frame_deadline_interval_ = false;
+  begin_frame_deadline_task_.Cancel();
+  begin_frame_deadline_task_time_ = base::TimeTicks();
+
+  if (ShouldDraw()) {
+    if (pending_swaps_ < max_pending_swaps_ && !root_surface_resources_locked_)
+      return DrawAndSwap();
+  } else {
+    // We are going idle, so reset expectations.
+    // TODO(eseckler): Should we avoid going idle if
+    // |expecting_root_surface_damage_because_of_resize_| is true?
+    expecting_root_surface_damage_because_of_resize_ = false;
+
+    StopObservingBeginFrames();
+  }
+  return false;
+}
+
+void DisplayScheduler::OnBeginFrameDeadline() {
+  TRACE_EVENT0("viz", "DisplayScheduler::OnBeginFrameDeadline");
+  DCHECK(inside_begin_frame_deadline_interval_);
+
+  bool did_draw = AttemptDrawAndSwap();
+  DidFinishFrame(did_draw);
+}
+
+void DisplayScheduler::DidFinishFrame(bool did_draw) {
+  DCHECK(begin_frame_source_);
+  // TODO(eseckler): Let client know that frame was completed.
+  begin_frame_source_->DidFinishFrame(this);
+}
+
+void DisplayScheduler::DidSwapBuffers() {
+  pending_swaps_++;
+  uint32_t swap_id = next_swap_id_++;
+  TRACE_EVENT_ASYNC_BEGIN0("viz", "DisplayScheduler:pending_swaps", swap_id);
+}
+
+void DisplayScheduler::DidReceiveSwapBuffersAck() {
+  uint32_t swap_id = next_swap_id_ - pending_swaps_;
+  pending_swaps_--;
+  TRACE_EVENT_ASYNC_END0("viz", "DisplayScheduler:pending_swaps", swap_id);
+  ScheduleBeginFrameDeadline();
+}
+
+}  // namespace viz
diff --git a/components/viz/service/display/display_scheduler.h b/components/viz/service/display/display_scheduler.h
new file mode 100644
index 0000000..8c5fefa0
--- /dev/null
+++ b/components/viz/service/display/display_scheduler.h
@@ -0,0 +1,136 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_SCHEDULER_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_SCHEDULER_H_
+
+#include <memory>
+
+#include "base/cancelable_callback.h"
+#include "base/containers/flat_map.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/single_thread_task_runner.h"
+#include "cc/output/renderer_settings.h"
+#include "cc/scheduler/begin_frame_source.h"
+#include "cc/surfaces/surface_observer.h"
+#include "components/viz/common/surface_id.h"
+#include "components/viz/service/viz_service_export.h"
+
+namespace viz {
+
+class BeginFrameSource;
+class SurfaceInfo;
+
+class VIZ_SERVICE_EXPORT DisplaySchedulerClient {
+ public:
+  virtual ~DisplaySchedulerClient() {}
+
+  virtual bool DrawAndSwap() = 0;
+  virtual bool SurfaceHasUndrawnFrame(const SurfaceId& surface_id) const = 0;
+  virtual bool SurfaceDamaged(const SurfaceId& surface_id,
+                              const cc::BeginFrameAck& ack) = 0;
+  virtual void SurfaceDiscarded(const SurfaceId& surface_id) = 0;
+};
+
+class VIZ_SERVICE_EXPORT DisplayScheduler : public cc::BeginFrameObserverBase,
+                                            public cc::SurfaceObserver {
+ public:
+  DisplayScheduler(cc::BeginFrameSource* begin_frame_source,
+                   base::SingleThreadTaskRunner* task_runner,
+                   int max_pending_swaps,
+                   bool wait_for_all_surfaces_before_draw = false);
+  ~DisplayScheduler() override;
+
+  void SetClient(DisplaySchedulerClient* client);
+
+  void SetVisible(bool visible);
+  void SetRootSurfaceResourcesLocked(bool locked);
+  void ForceImmediateSwapIfPossible();
+  virtual void DisplayResized();
+  virtual void SetNewRootSurface(const SurfaceId& root_surface_id);
+  virtual void ProcessSurfaceDamage(const SurfaceId& surface_id,
+                                    const cc::BeginFrameAck& ack,
+                                    bool display_damaged);
+
+  virtual void DidSwapBuffers();
+  void DidReceiveSwapBuffersAck();
+
+  void OutputSurfaceLost();
+
+  // BeginFrameObserverBase implementation.
+  bool OnBeginFrameDerivedImpl(const cc::BeginFrameArgs& args) override;
+  void OnBeginFrameSourcePausedChanged(bool paused) override;
+
+  // SurfaceObserver implementation.
+  void OnSurfaceCreated(const cc::SurfaceInfo& surface_info) override;
+  void OnSurfaceDestroyed(const SurfaceId& surface_id) override;
+  bool OnSurfaceDamaged(const SurfaceId& surface_id,
+                        const cc::BeginFrameAck& ack) override;
+  void OnSurfaceDiscarded(const SurfaceId& surface_id) override;
+  void OnSurfaceDamageExpected(const SurfaceId& surface_id,
+                               const cc::BeginFrameArgs& args) override;
+  void OnSurfaceWillDraw(const SurfaceId& surface_id) override;
+
+ protected:
+  enum class BeginFrameDeadlineMode { kImmediate, kRegular, kLate, kNone };
+  base::TimeTicks DesiredBeginFrameDeadlineTime() const;
+  BeginFrameDeadlineMode AdjustedBeginFrameDeadlineMode() const;
+  BeginFrameDeadlineMode DesiredBeginFrameDeadlineMode() const;
+  virtual void ScheduleBeginFrameDeadline();
+  bool AttemptDrawAndSwap();
+  void OnBeginFrameDeadline();
+  bool DrawAndSwap();
+  void StartObservingBeginFrames();
+  void StopObservingBeginFrames();
+  bool ShouldDraw();
+  void DidFinishFrame(bool did_draw);
+  // Updates |has_pending_surfaces_| and returns whether its value changed.
+  bool UpdateHasPendingSurfaces();
+
+  DisplaySchedulerClient* client_;
+  cc::BeginFrameSource* begin_frame_source_;
+  base::SingleThreadTaskRunner* task_runner_;
+
+  cc::BeginFrameArgs current_begin_frame_args_;
+  base::Closure begin_frame_deadline_closure_;
+  base::CancelableClosure begin_frame_deadline_task_;
+  base::TimeTicks begin_frame_deadline_task_time_;
+
+  base::CancelableClosure missed_begin_frame_task_;
+  bool inside_surface_damaged_;
+
+  bool visible_;
+  bool output_surface_lost_;
+  bool root_surface_resources_locked_;
+
+  bool inside_begin_frame_deadline_interval_;
+  bool needs_draw_;
+  bool expecting_root_surface_damage_because_of_resize_;
+  bool has_pending_surfaces_;
+
+  struct SurfaceBeginFrameState {
+    cc::BeginFrameArgs last_args;
+    cc::BeginFrameAck last_ack;
+  };
+  base::flat_map<SurfaceId, SurfaceBeginFrameState> surface_states_;
+
+  int next_swap_id_;
+  int pending_swaps_;
+  int max_pending_swaps_;
+  bool wait_for_all_surfaces_before_draw_;
+
+  bool observing_begin_frame_source_;
+
+  SurfaceId root_surface_id_;
+
+  base::WeakPtrFactory<DisplayScheduler> weak_ptr_factory_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(DisplayScheduler);
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_DISPLAY_SCHEDULER_H_
diff --git a/components/viz/service/display/display_scheduler_unittest.cc b/components/viz/service/display/display_scheduler_unittest.cc
new file mode 100644
index 0000000..120a4cd8
--- /dev/null
+++ b/components/viz/service/display/display_scheduler_unittest.cc
@@ -0,0 +1,735 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/display/display_scheduler.h"
+
+#include "base/logging.h"
+#include "base/stl_util.h"
+#include "base/test/null_task_runner.h"
+#include "base/test/simple_test_tick_clock.h"
+#include "base/trace_event/trace_event.h"
+#include "cc/output/begin_frame_args.h"
+#include "cc/surfaces/surface_info.h"
+#include "cc/test/fake_external_begin_frame_source.h"
+#include "cc/test/scheduler_test_common.h"
+#include "components/viz/service/display/display.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace viz {
+namespace {
+
+const int kMaxPendingSwaps = 1;
+
+static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1);
+
+class FakeDisplaySchedulerClient : public DisplaySchedulerClient {
+ public:
+  FakeDisplaySchedulerClient()
+      : draw_and_swap_count_(0), next_draw_and_swap_fails_(false) {}
+
+  ~FakeDisplaySchedulerClient() override {}
+
+  bool DrawAndSwap() override {
+    draw_and_swap_count_++;
+
+    bool success = !next_draw_and_swap_fails_;
+    next_draw_and_swap_fails_ = false;
+
+    if (success)
+      undrawn_surfaces_.clear();
+    return success;
+  }
+
+  bool SurfaceHasUndrawnFrame(const SurfaceId& surface_id) const override {
+    return base::ContainsKey(undrawn_surfaces_, surface_id);
+  }
+
+  bool SurfaceDamaged(const SurfaceId& surface_id,
+                      const cc::BeginFrameAck& ack) override {
+    return false;
+  }
+
+  void SurfaceDiscarded(const SurfaceId& surface_id) override {}
+
+  int draw_and_swap_count() const { return draw_and_swap_count_; }
+
+  void SetNextDrawAndSwapFails() { next_draw_and_swap_fails_ = true; }
+
+  void SurfaceDamaged(const SurfaceId& surface_id) {
+    undrawn_surfaces_.insert(surface_id);
+  }
+
+ protected:
+  int draw_and_swap_count_;
+  bool next_draw_and_swap_fails_;
+  std::set<SurfaceId> undrawn_surfaces_;
+};
+
+class TestDisplayScheduler : public DisplayScheduler {
+ public:
+  TestDisplayScheduler(cc::BeginFrameSource* begin_frame_source,
+                       cc::SurfaceManager* surface_manager,
+                       base::SingleThreadTaskRunner* task_runner,
+                       int max_pending_swaps,
+                       bool wait_for_all_surfaces_before_draw)
+      : DisplayScheduler(begin_frame_source,
+                         task_runner,
+                         max_pending_swaps,
+                         wait_for_all_surfaces_before_draw),
+        scheduler_begin_frame_deadline_count_(0) {}
+
+  base::TimeTicks DesiredBeginFrameDeadlineTimeForTest() {
+    return DesiredBeginFrameDeadlineTime();
+  }
+
+  void BeginFrameDeadlineForTest() {
+    // Ensure that any missed BeginFrames were handled by the scheduler. We need
+    // to run the scheduled task ourselves since the NullTaskRunner won't.
+    if (!missed_begin_frame_task_.IsCancelled())
+      missed_begin_frame_task_.callback().Run();
+    OnBeginFrameDeadline();
+  }
+
+  void ScheduleBeginFrameDeadline() override {
+    scheduler_begin_frame_deadline_count_++;
+    DisplayScheduler::ScheduleBeginFrameDeadline();
+  }
+
+  int scheduler_begin_frame_deadline_count() {
+    return scheduler_begin_frame_deadline_count_;
+  }
+
+  bool inside_begin_frame_deadline_interval() {
+    return inside_begin_frame_deadline_interval_;
+  }
+
+  bool has_pending_surfaces() { return has_pending_surfaces_; }
+
+ protected:
+  int scheduler_begin_frame_deadline_count_;
+};
+
+class DisplaySchedulerTest : public testing::Test {
+ public:
+  explicit DisplaySchedulerTest(bool wait_for_all_surfaces_before_draw = false)
+      : fake_begin_frame_source_(0.f, false),
+        task_runner_(new base::NullTaskRunner),
+        scheduler_(&fake_begin_frame_source_,
+                   &surface_manager_,
+                   task_runner_.get(),
+                   kMaxPendingSwaps,
+                   wait_for_all_surfaces_before_draw) {
+    now_src_.Advance(base::TimeDelta::FromMicroseconds(10000));
+    surface_manager_.AddObserver(&scheduler_);
+    scheduler_.SetClient(&client_);
+  }
+
+  ~DisplaySchedulerTest() override {
+    surface_manager_.RemoveObserver(&scheduler_);
+  }
+
+  void SetUp() override { scheduler_.SetRootSurfaceResourcesLocked(false); }
+
+  void AdvanceTimeAndBeginFrameForTest(
+      const std::vector<SurfaceId>& observing_surfaces) {
+    now_src_.Advance(base::TimeDelta::FromMicroseconds(10000));
+    // FakeBeginFrameSource deals with |source_id| and |sequence_number|.
+    last_begin_frame_args_ = fake_begin_frame_source_.CreateBeginFrameArgs(
+        BEGINFRAME_FROM_HERE, &now_src_);
+    fake_begin_frame_source_.TestOnBeginFrame(last_begin_frame_args_);
+    for (const auto& surface_id : observing_surfaces)
+      scheduler_.OnSurfaceDamageExpected(surface_id, last_begin_frame_args_);
+  }
+
+  void SurfaceDamaged(const SurfaceId& surface_id) {
+    client_.SurfaceDamaged(surface_id);
+    scheduler_.ProcessSurfaceDamage(surface_id, AckForCurrentBeginFrame(),
+                                    true);
+  }
+
+ protected:
+  base::SimpleTestTickClock& now_src() { return now_src_; }
+  FakeDisplaySchedulerClient& client() { return client_; }
+  DisplayScheduler& scheduler() { return scheduler_; }
+  cc::BeginFrameAck AckForCurrentBeginFrame() {
+    DCHECK(last_begin_frame_args_.IsValid());
+    return cc::BeginFrameAck(last_begin_frame_args_.source_id,
+                             last_begin_frame_args_.sequence_number,
+                             last_begin_frame_args_.sequence_number, true);
+  }
+
+  cc::FakeExternalBeginFrameSource fake_begin_frame_source_;
+  cc::BeginFrameArgs last_begin_frame_args_;
+
+  base::SimpleTestTickClock now_src_;
+  scoped_refptr<base::NullTaskRunner> task_runner_;
+  cc::SurfaceManager surface_manager_;
+  FakeDisplaySchedulerClient client_;
+  TestDisplayScheduler scheduler_;
+};
+
+TEST_F(DisplaySchedulerTest, ResizeHasLateDeadlineUntilNewRootSurface) {
+  SurfaceId root_surface_id1(
+      kArbitraryFrameSinkId,
+      LocalSurfaceId(1, base::UnguessableToken::Create()));
+  SurfaceId root_surface_id2(
+      kArbitraryFrameSinkId,
+      LocalSurfaceId(2, base::UnguessableToken::Create()));
+  SurfaceId sid1(kArbitraryFrameSinkId,
+                 LocalSurfaceId(3, base::UnguessableToken::Create()));
+  base::TimeTicks late_deadline;
+
+  scheduler_.SetVisible(true);
+
+  // Go trough an initial BeginFrame cycle with the root surface.
+  AdvanceTimeAndBeginFrameForTest(std::vector<SurfaceId>());
+  scheduler_.SetNewRootSurface(root_surface_id1);
+  scheduler_.BeginFrameDeadlineForTest();
+
+  // Resize on the next begin frame cycle should cause the deadline to wait
+  // for a new root surface.
+  AdvanceTimeAndBeginFrameForTest({root_surface_id1});
+  late_deadline = now_src().NowTicks() + cc::BeginFrameArgs::DefaultInterval();
+  SurfaceDamaged(sid1);
+  EXPECT_GT(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.DisplayResized();
+  EXPECT_EQ(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.OnSurfaceDestroyed(root_surface_id1);
+  scheduler_.SetNewRootSurface(root_surface_id2);
+  EXPECT_GE(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.BeginFrameDeadlineForTest();
+
+  // Verify deadline goes back to normal after resize.
+  late_deadline = now_src().NowTicks() + cc::BeginFrameArgs::DefaultInterval();
+  AdvanceTimeAndBeginFrameForTest({root_surface_id2, sid1});
+  SurfaceDamaged(sid1);
+  EXPECT_GT(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  SurfaceDamaged(root_surface_id2);
+  EXPECT_GE(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.BeginFrameDeadlineForTest();
+}
+
+TEST_F(DisplaySchedulerTest, ResizeHasLateDeadlineUntilDamagedSurface) {
+  SurfaceId root_surface_id(
+      kArbitraryFrameSinkId,
+      LocalSurfaceId(1, base::UnguessableToken::Create()));
+  SurfaceId sid1(kArbitraryFrameSinkId,
+                 LocalSurfaceId(2, base::UnguessableToken::Create()));
+  base::TimeTicks late_deadline;
+
+  scheduler_.SetVisible(true);
+
+  // Go trough an initial BeginFrame cycle with the root surface.
+  AdvanceTimeAndBeginFrameForTest(std::vector<SurfaceId>());
+  scheduler_.SetNewRootSurface(root_surface_id);
+  scheduler_.BeginFrameDeadlineForTest();
+
+  // Resize on the next begin frame cycle should cause the deadline to wait
+  // for a new root surface.
+  AdvanceTimeAndBeginFrameForTest({root_surface_id});
+  late_deadline = now_src().NowTicks() + cc::BeginFrameArgs::DefaultInterval();
+  SurfaceDamaged(sid1);
+  EXPECT_GT(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.DisplayResized();
+  EXPECT_EQ(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  SurfaceDamaged(root_surface_id);
+  EXPECT_GE(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.BeginFrameDeadlineForTest();
+
+  // Verify deadline goes back to normal after resize.
+  AdvanceTimeAndBeginFrameForTest({root_surface_id, sid1});
+  late_deadline = now_src().NowTicks() + cc::BeginFrameArgs::DefaultInterval();
+  SurfaceDamaged(sid1);
+  EXPECT_GT(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  SurfaceDamaged(root_surface_id);
+  EXPECT_GE(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.BeginFrameDeadlineForTest();
+}
+
+TEST_F(DisplaySchedulerTest, SurfaceDamaged) {
+  SurfaceId root_surface_id(
+      kArbitraryFrameSinkId,
+      LocalSurfaceId(1, base::UnguessableToken::Create()));
+  SurfaceId sid1(kArbitraryFrameSinkId,
+                 LocalSurfaceId(2, base::UnguessableToken::Create()));
+  SurfaceId sid2(kArbitraryFrameSinkId,
+                 LocalSurfaceId(3, base::UnguessableToken::Create()));
+
+  scheduler_.SetVisible(true);
+  scheduler_.SetNewRootSurface(root_surface_id);
+
+  // Set surface1 as active via SurfaceDamageExpected().
+  AdvanceTimeAndBeginFrameForTest({sid1});
+
+  // Damage only from surface 2 (inactive) does not trigger deadline early.
+  SurfaceDamaged(sid2);
+  EXPECT_TRUE(scheduler_.has_pending_surfaces());
+  EXPECT_LT(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+
+  // Damage from surface 1 triggers deadline early.
+  SurfaceDamaged(sid1);
+  EXPECT_FALSE(scheduler_.has_pending_surfaces());
+  EXPECT_GE(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.BeginFrameDeadlineForTest();
+
+  // Set both surface 1 and 2 as active via SurfaceDamageExpected().
+  AdvanceTimeAndBeginFrameForTest({sid1, sid2});
+
+  // Deadline doesn't trigger early until surface 1 and 2 are both damaged.
+  EXPECT_LT(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  SurfaceDamaged(sid1);
+  EXPECT_LT(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  SurfaceDamaged(sid2);
+  EXPECT_GE(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.BeginFrameDeadlineForTest();
+
+  // Surface damage with |!has_damage| triggers early deadline if other damage
+  // exists.
+  AdvanceTimeAndBeginFrameForTest({sid1, sid2});
+  EXPECT_LT(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  SurfaceDamaged(sid2);
+  EXPECT_LT(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  cc::BeginFrameAck ack = AckForCurrentBeginFrame();
+  ack.has_damage = false;
+  scheduler_.ProcessSurfaceDamage(sid1, ack, false);
+  EXPECT_GE(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.BeginFrameDeadlineForTest();
+
+  // Surface damage with |!has_damage| does not trigger early deadline if no
+  // other damage exists.
+  AdvanceTimeAndBeginFrameForTest({sid1});
+  EXPECT_LT(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  ack = AckForCurrentBeginFrame();
+  ack.has_damage = false;
+  scheduler_.ProcessSurfaceDamage(sid1, ack, false);
+  EXPECT_LT(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.BeginFrameDeadlineForTest();
+
+  // System should be idle now.
+  AdvanceTimeAndBeginFrameForTest(std::vector<SurfaceId>());
+  EXPECT_FALSE(scheduler_.inside_begin_frame_deadline_interval());
+
+  // Surface damage with |!display_damaged| does not affect needs_draw and
+  // scheduler stays idle.
+  scheduler_.ProcessSurfaceDamage(sid1, AckForCurrentBeginFrame(), false);
+  EXPECT_FALSE(scheduler_.inside_begin_frame_deadline_interval());
+
+  // Deadline should trigger early if child surfaces are idle and
+  // we get damage on the root surface.
+  scheduler_.OnSurfaceDamageExpected(root_surface_id, last_begin_frame_args_);
+  EXPECT_FALSE(scheduler_.inside_begin_frame_deadline_interval());
+  SurfaceDamaged(root_surface_id);
+  EXPECT_GE(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.BeginFrameDeadlineForTest();
+}
+
+class DisplaySchedulerWaitForAllSurfacesTest : public DisplaySchedulerTest {
+ public:
+  DisplaySchedulerWaitForAllSurfacesTest()
+      : DisplaySchedulerTest(true /* wait_for_all_surfaces_before_draw */) {}
+};
+
+TEST_F(DisplaySchedulerWaitForAllSurfacesTest, WaitForAllSurfacesBeforeDraw) {
+  SurfaceId root_surface_id(
+      kArbitraryFrameSinkId,
+      LocalSurfaceId(1, base::UnguessableToken::Create()));
+  SurfaceId sid1(kArbitraryFrameSinkId,
+                 LocalSurfaceId(2, base::UnguessableToken::Create()));
+  SurfaceId sid2(kArbitraryFrameSinkId,
+                 LocalSurfaceId(3, base::UnguessableToken::Create()));
+
+  scheduler_.SetVisible(true);
+  scheduler_.SetNewRootSurface(root_surface_id);
+
+  // Set surface1 as active via SurfaceDamageExpected().
+  AdvanceTimeAndBeginFrameForTest({sid1});
+
+  // Deadline is blocked indefinitely until surface 1 is damaged.
+  EXPECT_EQ(base::TimeTicks::Max(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+
+  // Damage only from surface 2 (inactive) does not change deadline.
+  SurfaceDamaged(sid2);
+  EXPECT_TRUE(scheduler_.has_pending_surfaces());
+  EXPECT_EQ(base::TimeTicks::Max(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+
+  // Damage from surface 1 triggers deadline immediately.
+  SurfaceDamaged(sid1);
+  EXPECT_FALSE(scheduler_.has_pending_surfaces());
+  EXPECT_GE(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.BeginFrameDeadlineForTest();
+
+  // Surface damage with |!has_damage| triggers immediate deadline if other
+  // damage exists.
+  AdvanceTimeAndBeginFrameForTest({sid1, sid2});
+  EXPECT_EQ(base::TimeTicks::Max(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  SurfaceDamaged(sid2);
+  EXPECT_EQ(base::TimeTicks::Max(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  cc::BeginFrameAck ack = AckForCurrentBeginFrame();
+  ack.has_damage = false;
+  scheduler_.ProcessSurfaceDamage(sid1, ack, false);
+  EXPECT_GE(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.BeginFrameDeadlineForTest();
+
+  // Surface damage with |!has_damage| also triggers immediate deadline even if
+  // no other damage exists.
+  AdvanceTimeAndBeginFrameForTest({sid1});
+  EXPECT_EQ(base::TimeTicks::Max(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  ack = AckForCurrentBeginFrame();
+  ack.has_damage = false;
+  scheduler_.ProcessSurfaceDamage(sid1, ack, false);
+  EXPECT_GE(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.BeginFrameDeadlineForTest();
+
+  // System should be idle now because we had a frame without damage. Restore it
+  // to active state (DisplayScheduler observing BeginFrames) for the next test.
+  AdvanceTimeAndBeginFrameForTest(std::vector<SurfaceId>());
+  EXPECT_FALSE(scheduler_.inside_begin_frame_deadline_interval());
+  SurfaceDamaged(sid1);
+  scheduler_.BeginFrameDeadlineForTest();
+
+  // BeginFrame without expected surface damage triggers immediate deadline.
+  AdvanceTimeAndBeginFrameForTest(std::vector<SurfaceId>());
+  EXPECT_TRUE(scheduler_.inside_begin_frame_deadline_interval());
+  EXPECT_GE(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.BeginFrameDeadlineForTest();
+}
+
+TEST_F(DisplaySchedulerTest, OutputSurfaceLost) {
+  SurfaceId root_surface_id(
+      kArbitraryFrameSinkId,
+      LocalSurfaceId(1, base::UnguessableToken::Create()));
+  SurfaceId sid1(kArbitraryFrameSinkId,
+                 LocalSurfaceId(2, base::UnguessableToken::Create()));
+
+  scheduler_.SetVisible(true);
+  scheduler_.SetNewRootSurface(root_surface_id);
+
+  // DrawAndSwap normally.
+  AdvanceTimeAndBeginFrameForTest({sid1});
+  EXPECT_LT(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  EXPECT_EQ(0, client_.draw_and_swap_count());
+  SurfaceDamaged(sid1);
+  scheduler_.BeginFrameDeadlineForTest();
+  EXPECT_EQ(1, client_.draw_and_swap_count());
+
+  // Deadline triggers immediately on OutputSurfaceLost.
+  AdvanceTimeAndBeginFrameForTest({sid1});
+  EXPECT_LT(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.OutputSurfaceLost();
+  EXPECT_GE(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+
+  // Deadline does not DrawAndSwap after OutputSurfaceLost.
+  EXPECT_EQ(1, client_.draw_and_swap_count());
+  SurfaceDamaged(sid1);
+  scheduler_.BeginFrameDeadlineForTest();
+  EXPECT_EQ(1, client_.draw_and_swap_count());
+}
+
+TEST_F(DisplaySchedulerTest, VisibleWithoutDamageNoTicks) {
+  SurfaceId root_surface_id(
+      kArbitraryFrameSinkId,
+      LocalSurfaceId(1, base::UnguessableToken::Create()));
+
+  EXPECT_EQ(0u, fake_begin_frame_source_.num_observers());
+  scheduler_.SetVisible(true);
+
+  // When becoming visible, don't start listening for begin frames until there
+  // is some damage.
+  EXPECT_EQ(0u, fake_begin_frame_source_.num_observers());
+  scheduler_.SetNewRootSurface(root_surface_id);
+
+  EXPECT_EQ(1u, fake_begin_frame_source_.num_observers());
+}
+
+TEST_F(DisplaySchedulerTest, VisibleWithDamageTicks) {
+  SurfaceId root_surface_id(
+      kArbitraryFrameSinkId,
+      LocalSurfaceId(1, base::UnguessableToken::Create()));
+  SurfaceId sid1(kArbitraryFrameSinkId,
+                 LocalSurfaceId(2, base::UnguessableToken::Create()));
+
+  scheduler_.SetNewRootSurface(root_surface_id);
+
+  // When there is damage, start listening for begin frames once becoming
+  // visible.
+  EXPECT_EQ(0u, fake_begin_frame_source_.num_observers());
+  scheduler_.SetVisible(true);
+
+  EXPECT_EQ(1u, fake_begin_frame_source_.num_observers());
+}
+
+TEST_F(DisplaySchedulerTest, Visibility) {
+  SurfaceId root_surface_id(
+      kArbitraryFrameSinkId,
+      LocalSurfaceId(1, base::UnguessableToken::Create()));
+  SurfaceId sid1(kArbitraryFrameSinkId,
+                 LocalSurfaceId(2, base::UnguessableToken::Create()));
+
+  // Set the root surface.
+  scheduler_.SetNewRootSurface(root_surface_id);
+  scheduler_.SetVisible(true);
+  EXPECT_EQ(1u, fake_begin_frame_source_.num_observers());
+
+  // DrawAndSwap normally.
+  AdvanceTimeAndBeginFrameForTest({sid1});
+  EXPECT_LT(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  EXPECT_EQ(0, client_.draw_and_swap_count());
+  SurfaceDamaged(sid1);
+  scheduler_.BeginFrameDeadlineForTest();
+  EXPECT_EQ(1, client_.draw_and_swap_count());
+
+  AdvanceTimeAndBeginFrameForTest({sid1});
+  EXPECT_LT(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+
+  // Become not visible.
+  scheduler_.SetVisible(false);
+
+  // It will stop listening for begin frames after the current deadline.
+  EXPECT_EQ(1u, fake_begin_frame_source_.num_observers());
+
+  // Deadline does not DrawAndSwap when not visible.
+  EXPECT_EQ(1, client_.draw_and_swap_count());
+  scheduler_.BeginFrameDeadlineForTest();
+  EXPECT_EQ(1, client_.draw_and_swap_count());
+  // Now it stops listening for begin frames.
+  EXPECT_EQ(0u, fake_begin_frame_source_.num_observers());
+
+  // Does not start listening for begin frames when becoming visible without
+  // damage.
+  scheduler_.SetVisible(true);
+  EXPECT_EQ(0u, fake_begin_frame_source_.num_observers());
+  scheduler_.SetVisible(false);
+
+  // Does not start listening for begin frames when damage arrives.
+  SurfaceDamaged(sid1);
+  EXPECT_EQ(0u, fake_begin_frame_source_.num_observers());
+
+  // But does when becoming visible with damage again.
+  scheduler_.SetVisible(true);
+  EXPECT_EQ(1u, fake_begin_frame_source_.num_observers());
+}
+
+TEST_F(DisplaySchedulerTest, ResizeCausesSwap) {
+  SurfaceId root_surface_id(
+      kArbitraryFrameSinkId,
+      LocalSurfaceId(1, base::UnguessableToken::Create()));
+  SurfaceId sid1(kArbitraryFrameSinkId,
+                 LocalSurfaceId(2, base::UnguessableToken::Create()));
+
+  scheduler_.SetVisible(true);
+  scheduler_.SetNewRootSurface(root_surface_id);
+
+  // DrawAndSwap normally.
+  AdvanceTimeAndBeginFrameForTest({sid1});
+  EXPECT_LT(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  EXPECT_EQ(0, client_.draw_and_swap_count());
+  SurfaceDamaged(sid1);
+  scheduler_.BeginFrameDeadlineForTest();
+  EXPECT_EQ(1, client_.draw_and_swap_count());
+
+  scheduler_.DisplayResized();
+  AdvanceTimeAndBeginFrameForTest(std::vector<SurfaceId>());
+  // DisplayResized should trigger a swap to happen.
+  scheduler_.BeginFrameDeadlineForTest();
+  EXPECT_EQ(2, client_.draw_and_swap_count());
+}
+
+TEST_F(DisplaySchedulerTest, RootSurfaceResourcesLocked) {
+  SurfaceId root_surface_id(
+      kArbitraryFrameSinkId,
+      LocalSurfaceId(1, base::UnguessableToken::Create()));
+  SurfaceId sid1(kArbitraryFrameSinkId,
+                 LocalSurfaceId(2, base::UnguessableToken::Create()));
+  base::TimeTicks late_deadline;
+
+  scheduler_.SetVisible(true);
+  scheduler_.SetNewRootSurface(root_surface_id);
+
+  // DrawAndSwap normally.
+  AdvanceTimeAndBeginFrameForTest({sid1});
+  EXPECT_LT(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  EXPECT_EQ(0, client_.draw_and_swap_count());
+  SurfaceDamaged(sid1);
+  scheduler_.BeginFrameDeadlineForTest();
+  EXPECT_EQ(1, client_.draw_and_swap_count());
+
+  // Deadline triggers late while root resources are locked.
+  AdvanceTimeAndBeginFrameForTest({sid1});
+  late_deadline = now_src().NowTicks() + cc::BeginFrameArgs::DefaultInterval();
+  SurfaceDamaged(sid1);
+  EXPECT_GT(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.SetRootSurfaceResourcesLocked(true);
+  EXPECT_EQ(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+
+  // Deadline does not DrawAndSwap while root resources are locked.
+  EXPECT_EQ(1, client_.draw_and_swap_count());
+  SurfaceDamaged(sid1);
+  scheduler_.BeginFrameDeadlineForTest();
+  EXPECT_EQ(1, client_.draw_and_swap_count());
+
+  //  Deadline triggers normally when root resources are unlocked.
+  AdvanceTimeAndBeginFrameForTest({sid1, root_surface_id});
+  late_deadline = now_src().NowTicks() + cc::BeginFrameArgs::DefaultInterval();
+  SurfaceDamaged(sid1);
+  EXPECT_EQ(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  scheduler_.SetRootSurfaceResourcesLocked(false);
+  SurfaceDamaged(root_surface_id);
+  EXPECT_EQ(base::TimeTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+
+  EXPECT_EQ(1, client_.draw_and_swap_count());
+  scheduler_.BeginFrameDeadlineForTest();
+  EXPECT_EQ(2, client_.draw_and_swap_count());
+}
+
+TEST_F(DisplaySchedulerTest, DidSwapBuffers) {
+  SurfaceId root_surface_id(
+      kArbitraryFrameSinkId,
+      LocalSurfaceId(1, base::UnguessableToken::Create()));
+  SurfaceId sid1(kArbitraryFrameSinkId,
+                 LocalSurfaceId(2, base::UnguessableToken::Create()));
+  SurfaceId sid2(kArbitraryFrameSinkId,
+                 LocalSurfaceId(3, base::UnguessableToken::Create()));
+
+  scheduler_.SetVisible(true);
+  scheduler_.SetNewRootSurface(root_surface_id);
+
+  // Set surface 1 and 2 as active.
+  AdvanceTimeAndBeginFrameForTest({sid1, sid2});
+
+  // DrawAndSwap normally.
+  EXPECT_LT(now_src().NowTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  EXPECT_EQ(0, client_.draw_and_swap_count());
+  SurfaceDamaged(sid1);
+  SurfaceDamaged(sid2);
+  scheduler_.BeginFrameDeadlineForTest();
+  EXPECT_EQ(1, client_.draw_and_swap_count());
+  scheduler_.DidSwapBuffers();
+
+  // Deadline triggers late when swap throttled.
+  AdvanceTimeAndBeginFrameForTest({sid1, sid2});
+  base::TimeTicks late_deadline =
+      now_src().NowTicks() + cc::BeginFrameArgs::DefaultInterval();
+  // Damage surface 1, but not surface 2 so we avoid triggering deadline
+  // early because all surfaces are ready.
+  SurfaceDamaged(sid1);
+  EXPECT_EQ(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+
+  // Don't draw and swap in deadline while swap throttled.
+  EXPECT_EQ(1, client_.draw_and_swap_count());
+  scheduler_.BeginFrameDeadlineForTest();
+  EXPECT_EQ(1, client_.draw_and_swap_count());
+
+  // Deadline triggers normally once not swap throttled.
+  // Damage from previous BeginFrame should cary over, so don't damage again.
+  scheduler_.DidReceiveSwapBuffersAck();
+  AdvanceTimeAndBeginFrameForTest({sid2});
+  base::TimeTicks expected_deadline =
+      scheduler_.LastUsedBeginFrameArgs().deadline -
+      cc::BeginFrameArgs::DefaultEstimatedParentDrawTime();
+  EXPECT_EQ(expected_deadline,
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  // Still waiting for surface 2. Once it updates, deadline should trigger
+  // immediately again.
+  SurfaceDamaged(sid2);
+  EXPECT_EQ(base::TimeTicks(),
+            scheduler_.DesiredBeginFrameDeadlineTimeForTest());
+  // Draw and swap now that we aren't throttled.
+  EXPECT_EQ(1, client_.draw_and_swap_count());
+  scheduler_.BeginFrameDeadlineForTest();
+  EXPECT_EQ(2, client_.draw_and_swap_count());
+}
+
+// This test verfies that we try to reschedule the deadline
+// after any event that may change what deadline we want.
+TEST_F(DisplaySchedulerTest, ScheduleBeginFrameDeadline) {
+  SurfaceId root_surface_id(
+      kArbitraryFrameSinkId,
+      LocalSurfaceId(1, base::UnguessableToken::Create()));
+  SurfaceId sid1(kArbitraryFrameSinkId,
+                 LocalSurfaceId(2, base::UnguessableToken::Create()));
+  int count = 1;
+  EXPECT_EQ(count, scheduler_.scheduler_begin_frame_deadline_count());
+
+  scheduler_.SetVisible(true);
+  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
+
+  scheduler_.SetVisible(true);
+  EXPECT_EQ(count, scheduler_.scheduler_begin_frame_deadline_count());
+
+  scheduler_.SetVisible(false);
+  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
+
+  // Set the root surface while not visible.
+  scheduler_.SetNewRootSurface(root_surface_id);
+  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
+
+  scheduler_.SetVisible(true);
+  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
+
+  // Set the root surface while visible.
+  scheduler_.SetNewRootSurface(root_surface_id);
+  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
+
+  AdvanceTimeAndBeginFrameForTest(std::vector<SurfaceId>());
+  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
+
+  scheduler_.BeginFrameDeadlineForTest();
+  scheduler_.DidSwapBuffers();
+  AdvanceTimeAndBeginFrameForTest(std::vector<SurfaceId>());
+  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
+
+  scheduler_.DidReceiveSwapBuffersAck();
+  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
+
+  scheduler_.DisplayResized();
+  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
+
+  scheduler_.SetNewRootSurface(root_surface_id);
+  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
+
+  SurfaceDamaged(sid1);
+  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
+
+  scheduler_.SetRootSurfaceResourcesLocked(true);
+  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
+
+  scheduler_.OutputSurfaceLost();
+  EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count());
+}
+
+}  // namespace
+}  // namespace viz
diff --git a/components/viz/service/display/display_unittest.cc b/components/viz/service/display/display_unittest.cc
new file mode 100644
index 0000000..3858e3b
--- /dev/null
+++ b/components/viz/service/display/display_unittest.cc
@@ -0,0 +1,658 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/display/display.h"
+
+#include <utility>
+
+#include "base/memory/ptr_util.h"
+#include "base/test/null_task_runner.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/output/copy_output_result.h"
+#include "cc/output/texture_mailbox_deleter.h"
+#include "cc/quads/render_pass.h"
+#include "cc/scheduler/begin_frame_source.h"
+#include "cc/surfaces/frame_sink_manager.h"
+#include "cc/surfaces/surface.h"
+#include "cc/surfaces/surface_manager.h"
+#include "cc/test/compositor_frame_helpers.h"
+#include "cc/test/fake_output_surface.h"
+#include "cc/test/scheduler_test_common.h"
+#include "cc/test/test_shared_bitmap_manager.h"
+#include "components/viz/common/frame_sink_id.h"
+#include "components/viz/common/local_surface_id_allocator.h"
+#include "components/viz/common/resources/shared_bitmap_manager.h"
+#include "components/viz/service/display/display_client.h"
+#include "components/viz/service/display/display_scheduler.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
+#include "gpu/GLES2/gl2extchromium.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::AnyNumber;
+
+namespace viz {
+namespace {
+
+static constexpr FrameSinkId kArbitraryFrameSinkId(3, 3);
+static constexpr FrameSinkId kAnotherFrameSinkId(4, 4);
+
+class TestSoftwareOutputDevice : public cc::SoftwareOutputDevice {
+ public:
+  TestSoftwareOutputDevice() {}
+
+  gfx::Rect damage_rect() const { return damage_rect_; }
+  gfx::Size viewport_pixel_size() const { return viewport_pixel_size_; }
+};
+
+class TestDisplayScheduler : public DisplayScheduler {
+ public:
+  explicit TestDisplayScheduler(cc::BeginFrameSource* begin_frame_source,
+                                base::SingleThreadTaskRunner* task_runner)
+      : DisplayScheduler(begin_frame_source, task_runner, 1),
+        damaged(false),
+        display_resized_(false),
+        has_new_root_surface(false),
+        swapped(false) {}
+
+  ~TestDisplayScheduler() override {}
+
+  void DisplayResized() override { display_resized_ = true; }
+
+  void SetNewRootSurface(const SurfaceId& root_surface_id) override {
+    has_new_root_surface = true;
+  }
+
+  void ProcessSurfaceDamage(const SurfaceId& surface_id,
+                            const cc::BeginFrameAck& ack,
+                            bool display_damaged) override {
+    if (display_damaged) {
+      damaged = true;
+      needs_draw_ = true;
+    }
+  }
+
+  void DidSwapBuffers() override { swapped = true; }
+
+  void ResetDamageForTest() {
+    damaged = false;
+    display_resized_ = false;
+    has_new_root_surface = false;
+  }
+
+  bool damaged;
+  bool display_resized_;
+  bool has_new_root_surface;
+  bool swapped;
+};
+
+class DisplayTest : public testing::Test {
+ public:
+  DisplayTest()
+      : support_(CompositorFrameSinkSupport::Create(
+            nullptr,
+            &manager_,
+            kArbitraryFrameSinkId,
+            true /* is_root */,
+            true /* handles_frame_sink_id_invalidation */,
+            true /* needs_sync_points */)),
+        task_runner_(new base::NullTaskRunner) {}
+
+  ~DisplayTest() override { support_->EvictCurrentSurface(); }
+
+  void SetUpDisplay(const cc::RendererSettings& settings,
+                    std::unique_ptr<cc::TestWebGraphicsContext3D> context) {
+    begin_frame_source_.reset(new cc::StubBeginFrameSource);
+
+    std::unique_ptr<cc::FakeOutputSurface> output_surface;
+    if (context) {
+      auto provider = cc::TestContextProvider::Create(std::move(context));
+      provider->BindToCurrentThread();
+      output_surface = cc::FakeOutputSurface::Create3d(std::move(provider));
+    } else {
+      auto device = base::MakeUnique<TestSoftwareOutputDevice>();
+      software_output_device_ = device.get();
+      output_surface = cc::FakeOutputSurface::CreateSoftware(std::move(device));
+    }
+    output_surface_ = output_surface.get();
+    auto scheduler = base::MakeUnique<TestDisplayScheduler>(
+        begin_frame_source_.get(), task_runner_.get());
+    scheduler_ = scheduler.get();
+    display_ = CreateDisplay(settings, kArbitraryFrameSinkId,
+                             std::move(scheduler), std::move(output_surface));
+    manager_.RegisterBeginFrameSource(begin_frame_source_.get(),
+                                      kArbitraryFrameSinkId);
+  }
+
+  std::unique_ptr<Display> CreateDisplay(
+      const cc::RendererSettings& settings,
+      const FrameSinkId& frame_sink_id,
+      std::unique_ptr<DisplayScheduler> scheduler,
+      std::unique_ptr<cc::OutputSurface> output_surface) {
+    auto display = base::MakeUnique<Display>(
+        &shared_bitmap_manager_, nullptr /* gpu_memory_buffer_manager */,
+        settings, frame_sink_id, std::move(output_surface),
+        std::move(scheduler),
+        base::MakeUnique<cc::TextureMailboxDeleter>(task_runner_.get()));
+    display->SetVisible(true);
+    return display;
+  }
+
+  void TearDownDisplay() {
+    // Only call UnregisterBeginFrameSource if SetupDisplay has been called.
+    if (begin_frame_source_)
+      manager_.UnregisterBeginFrameSource(begin_frame_source_.get());
+  }
+
+ protected:
+  void SubmitCompositorFrame(cc::RenderPassList* pass_list,
+                             const LocalSurfaceId& local_surface_id) {
+    cc::CompositorFrame frame = cc::test::MakeCompositorFrame();
+    pass_list->swap(frame.render_pass_list);
+
+    support_->SubmitCompositorFrame(local_surface_id, std::move(frame));
+  }
+
+  cc::FrameSinkManager manager_;
+  std::unique_ptr<CompositorFrameSinkSupport> support_;
+  LocalSurfaceIdAllocator id_allocator_;
+  scoped_refptr<base::NullTaskRunner> task_runner_;
+  cc::TestSharedBitmapManager shared_bitmap_manager_;
+  std::unique_ptr<cc::BeginFrameSource> begin_frame_source_;
+  std::unique_ptr<Display> display_;
+  TestSoftwareOutputDevice* software_output_device_ = nullptr;
+  cc::FakeOutputSurface* output_surface_ = nullptr;
+  TestDisplayScheduler* scheduler_ = nullptr;
+};
+
+class StubDisplayClient : public DisplayClient {
+ public:
+  void DisplayOutputSurfaceLost() override {}
+  void DisplayWillDrawAndSwap(
+      bool will_draw_and_swap,
+      const cc::RenderPassList& render_passes) override {}
+  void DisplayDidDrawAndSwap() override {}
+};
+
+void CopyCallback(bool* called, std::unique_ptr<cc::CopyOutputResult> result) {
+  *called = true;
+}
+
+// Check that frame is damaged and swapped only under correct conditions.
+TEST_F(DisplayTest, DisplayDamaged) {
+  cc::RendererSettings settings;
+  settings.partial_swap_enabled = true;
+  settings.finish_rendering_on_resize = true;
+  SetUpDisplay(settings, nullptr);
+  gfx::ColorSpace color_space_1 = gfx::ColorSpace::CreateXYZD50();
+  gfx::ColorSpace color_space_2 = gfx::ColorSpace::CreateSCRGBLinear();
+
+  StubDisplayClient client;
+  display_->Initialize(&client, manager_.surface_manager());
+  display_->SetColorSpace(color_space_1, color_space_1);
+
+  LocalSurfaceId local_surface_id(id_allocator_.GenerateId());
+  EXPECT_FALSE(scheduler_->damaged);
+  EXPECT_FALSE(scheduler_->has_new_root_surface);
+  display_->SetLocalSurfaceId(local_surface_id, 1.f);
+  EXPECT_FALSE(scheduler_->damaged);
+  EXPECT_FALSE(scheduler_->display_resized_);
+  EXPECT_TRUE(scheduler_->has_new_root_surface);
+
+  scheduler_->ResetDamageForTest();
+  display_->Resize(gfx::Size(100, 100));
+  EXPECT_FALSE(scheduler_->damaged);
+  EXPECT_TRUE(scheduler_->display_resized_);
+  EXPECT_FALSE(scheduler_->has_new_root_surface);
+
+  // First draw from surface should have full damage.
+  cc::RenderPassList pass_list;
+  auto pass = cc::RenderPass::Create();
+  pass->output_rect = gfx::Rect(0, 0, 100, 100);
+  pass->damage_rect = gfx::Rect(10, 10, 1, 1);
+  pass->id = 1u;
+  pass_list.push_back(std::move(pass));
+
+  scheduler_->ResetDamageForTest();
+  SubmitCompositorFrame(&pass_list, local_surface_id);
+  EXPECT_TRUE(scheduler_->damaged);
+  EXPECT_FALSE(scheduler_->display_resized_);
+  EXPECT_FALSE(scheduler_->has_new_root_surface);
+
+  EXPECT_FALSE(scheduler_->swapped);
+  EXPECT_EQ(0u, output_surface_->num_sent_frames());
+  EXPECT_EQ(gfx::ColorSpace(), output_surface_->last_reshape_color_space());
+  display_->DrawAndSwap();
+  EXPECT_EQ(color_space_1, output_surface_->last_reshape_color_space());
+  EXPECT_TRUE(scheduler_->swapped);
+  EXPECT_EQ(1u, output_surface_->num_sent_frames());
+  EXPECT_EQ(gfx::Size(100, 100),
+            software_output_device_->viewport_pixel_size());
+  EXPECT_EQ(gfx::Rect(0, 0, 100, 100), software_output_device_->damage_rect());
+  {
+    // Only damaged portion should be swapped.
+    pass = cc::RenderPass::Create();
+    pass->output_rect = gfx::Rect(0, 0, 100, 100);
+    pass->damage_rect = gfx::Rect(10, 10, 1, 1);
+    pass->id = 1u;
+
+    pass_list.push_back(std::move(pass));
+    scheduler_->ResetDamageForTest();
+    SubmitCompositorFrame(&pass_list, local_surface_id);
+    EXPECT_TRUE(scheduler_->damaged);
+    EXPECT_FALSE(scheduler_->display_resized_);
+    EXPECT_FALSE(scheduler_->has_new_root_surface);
+
+    scheduler_->swapped = false;
+    EXPECT_EQ(color_space_1, output_surface_->last_reshape_color_space());
+    display_->SetColorSpace(color_space_2, color_space_2);
+    display_->DrawAndSwap();
+    EXPECT_EQ(color_space_2, output_surface_->last_reshape_color_space());
+    EXPECT_TRUE(scheduler_->swapped);
+    EXPECT_EQ(2u, output_surface_->num_sent_frames());
+    EXPECT_EQ(gfx::Size(100, 100),
+              software_output_device_->viewport_pixel_size());
+    EXPECT_EQ(gfx::Rect(10, 10, 1, 1), software_output_device_->damage_rect());
+  }
+
+  {
+    // Pass has no damage so shouldn't be swapped.
+    pass = cc::RenderPass::Create();
+    pass->output_rect = gfx::Rect(0, 0, 100, 100);
+    pass->damage_rect = gfx::Rect(10, 10, 0, 0);
+    pass->id = 1u;
+
+    pass_list.push_back(std::move(pass));
+    scheduler_->ResetDamageForTest();
+    SubmitCompositorFrame(&pass_list, local_surface_id);
+    EXPECT_TRUE(scheduler_->damaged);
+    EXPECT_FALSE(scheduler_->display_resized_);
+    EXPECT_FALSE(scheduler_->has_new_root_surface);
+
+    scheduler_->swapped = false;
+    display_->DrawAndSwap();
+    EXPECT_TRUE(scheduler_->swapped);
+    EXPECT_EQ(2u, output_surface_->num_sent_frames());
+  }
+
+  {
+    // Pass is wrong size so shouldn't be swapped.
+    pass = cc::RenderPass::Create();
+    pass->output_rect = gfx::Rect(0, 0, 99, 99);
+    pass->damage_rect = gfx::Rect(10, 10, 10, 10);
+    pass->id = 1u;
+
+    local_surface_id = id_allocator_.GenerateId();
+    display_->SetLocalSurfaceId(local_surface_id, 1.f);
+
+    pass_list.push_back(std::move(pass));
+    scheduler_->ResetDamageForTest();
+    SubmitCompositorFrame(&pass_list, local_surface_id);
+    EXPECT_TRUE(scheduler_->damaged);
+    EXPECT_FALSE(scheduler_->display_resized_);
+    EXPECT_FALSE(scheduler_->has_new_root_surface);
+
+    scheduler_->swapped = false;
+    display_->DrawAndSwap();
+    EXPECT_TRUE(scheduler_->swapped);
+    EXPECT_EQ(2u, output_surface_->num_sent_frames());
+  }
+
+  {
+    // Previous frame wasn't swapped, so next swap should have full damage.
+    pass = cc::RenderPass::Create();
+    pass->output_rect = gfx::Rect(0, 0, 100, 100);
+    pass->damage_rect = gfx::Rect(10, 10, 0, 0);
+    pass->id = 1u;
+
+    local_surface_id = id_allocator_.GenerateId();
+    display_->SetLocalSurfaceId(local_surface_id, 1.f);
+
+    pass_list.push_back(std::move(pass));
+    scheduler_->ResetDamageForTest();
+    SubmitCompositorFrame(&pass_list, local_surface_id);
+    EXPECT_TRUE(scheduler_->damaged);
+    EXPECT_FALSE(scheduler_->display_resized_);
+    EXPECT_FALSE(scheduler_->has_new_root_surface);
+
+    scheduler_->swapped = false;
+    display_->DrawAndSwap();
+    EXPECT_TRUE(scheduler_->swapped);
+    EXPECT_EQ(3u, output_surface_->num_sent_frames());
+    EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
+              software_output_device_->damage_rect());
+  }
+
+  {
+    // Pass has copy output request so should be swapped.
+    pass = cc::RenderPass::Create();
+    pass->output_rect = gfx::Rect(0, 0, 100, 100);
+    pass->damage_rect = gfx::Rect(10, 10, 0, 0);
+    bool copy_called = false;
+    pass->copy_requests.push_back(cc::CopyOutputRequest::CreateRequest(
+        base::Bind(&CopyCallback, &copy_called)));
+    pass->id = 1u;
+
+    pass_list.push_back(std::move(pass));
+    scheduler_->ResetDamageForTest();
+    SubmitCompositorFrame(&pass_list, local_surface_id);
+    EXPECT_TRUE(scheduler_->damaged);
+    EXPECT_FALSE(scheduler_->display_resized_);
+    EXPECT_FALSE(scheduler_->has_new_root_surface);
+
+    scheduler_->swapped = false;
+    display_->DrawAndSwap();
+    EXPECT_TRUE(scheduler_->swapped);
+    EXPECT_EQ(4u, output_surface_->num_sent_frames());
+    EXPECT_TRUE(copy_called);
+  }
+
+  // Pass has no damage, so shouldn't be swapped, but latency info should be
+  // saved for next swap.
+  {
+    pass = cc::RenderPass::Create();
+    pass->output_rect = gfx::Rect(0, 0, 100, 100);
+    pass->damage_rect = gfx::Rect(10, 10, 0, 0);
+    pass->id = 1u;
+
+    pass_list.push_back(std::move(pass));
+    scheduler_->ResetDamageForTest();
+
+    cc::CompositorFrame frame = cc::test::MakeCompositorFrame();
+    pass_list.swap(frame.render_pass_list);
+    frame.metadata.latency_info.push_back(ui::LatencyInfo());
+
+    support_->SubmitCompositorFrame(local_surface_id, std::move(frame));
+    EXPECT_TRUE(scheduler_->damaged);
+    EXPECT_FALSE(scheduler_->display_resized_);
+    EXPECT_FALSE(scheduler_->has_new_root_surface);
+
+    scheduler_->swapped = false;
+    display_->DrawAndSwap();
+    EXPECT_TRUE(scheduler_->swapped);
+    EXPECT_EQ(4u, output_surface_->num_sent_frames());
+  }
+
+  // Resize should cause a swap if no frame was swapped at the previous size.
+  {
+    local_surface_id = id_allocator_.GenerateId();
+    display_->SetLocalSurfaceId(local_surface_id, 1.f);
+    scheduler_->swapped = false;
+    display_->Resize(gfx::Size(200, 200));
+    EXPECT_FALSE(scheduler_->swapped);
+    EXPECT_EQ(4u, output_surface_->num_sent_frames());
+
+    pass = cc::RenderPass::Create();
+    pass->output_rect = gfx::Rect(0, 0, 200, 200);
+    pass->damage_rect = gfx::Rect(10, 10, 10, 10);
+    pass->id = 1u;
+
+    pass_list.push_back(std::move(pass));
+    scheduler_->ResetDamageForTest();
+
+    cc::CompositorFrame frame = cc::test::MakeCompositorFrame();
+    pass_list.swap(frame.render_pass_list);
+
+    support_->SubmitCompositorFrame(local_surface_id, std::move(frame));
+    EXPECT_TRUE(scheduler_->damaged);
+    EXPECT_FALSE(scheduler_->display_resized_);
+    EXPECT_FALSE(scheduler_->has_new_root_surface);
+
+    scheduler_->swapped = false;
+    display_->Resize(gfx::Size(100, 100));
+    EXPECT_TRUE(scheduler_->swapped);
+    EXPECT_EQ(5u, output_surface_->num_sent_frames());
+
+    // Latency info from previous frame should be sent now.
+    EXPECT_EQ(1u, output_surface_->last_sent_frame()->latency_info.size());
+  }
+
+  {
+    local_surface_id = id_allocator_.GenerateId();
+    display_->SetLocalSurfaceId(local_surface_id, 1.0f);
+    // Surface that's damaged completely should be resized and swapped.
+    pass = cc::RenderPass::Create();
+    pass->output_rect = gfx::Rect(0, 0, 99, 99);
+    pass->damage_rect = gfx::Rect(0, 0, 99, 99);
+    pass->id = 1u;
+
+    pass_list.push_back(std::move(pass));
+    scheduler_->ResetDamageForTest();
+    SubmitCompositorFrame(&pass_list, local_surface_id);
+    EXPECT_TRUE(scheduler_->damaged);
+    EXPECT_FALSE(scheduler_->display_resized_);
+    EXPECT_FALSE(scheduler_->has_new_root_surface);
+
+    scheduler_->swapped = false;
+    display_->DrawAndSwap();
+    EXPECT_TRUE(scheduler_->swapped);
+    EXPECT_EQ(6u, output_surface_->num_sent_frames());
+    EXPECT_EQ(gfx::Size(100, 100),
+              software_output_device_->viewport_pixel_size());
+    EXPECT_EQ(gfx::Rect(0, 0, 100, 100),
+              software_output_device_->damage_rect());
+    EXPECT_EQ(0u, output_surface_->last_sent_frame()->latency_info.size());
+  }
+  TearDownDisplay();
+}
+
+// Check LatencyInfo storage is cleaned up if it exceeds the limit.
+TEST_F(DisplayTest, MaxLatencyInfoCap) {
+  cc::RendererSettings settings;
+  settings.partial_swap_enabled = true;
+  settings.finish_rendering_on_resize = true;
+  SetUpDisplay(settings, nullptr);
+  gfx::ColorSpace color_space_1 = gfx::ColorSpace::CreateXYZD50();
+  gfx::ColorSpace color_space_2 = gfx::ColorSpace::CreateSCRGBLinear();
+
+  StubDisplayClient client;
+  display_->Initialize(&client, manager_.surface_manager());
+  display_->SetColorSpace(color_space_1, color_space_1);
+
+  LocalSurfaceId local_surface_id(id_allocator_.GenerateId());
+  display_->SetLocalSurfaceId(local_surface_id, 1.f);
+
+  scheduler_->ResetDamageForTest();
+  display_->Resize(gfx::Size(100, 100));
+
+  cc::RenderPassList pass_list;
+  auto pass = cc::RenderPass::Create();
+  pass->output_rect = gfx::Rect(0, 0, 100, 100);
+  pass->damage_rect = gfx::Rect(10, 10, 1, 1);
+  pass->id = 1u;
+  pass_list.push_back(std::move(pass));
+
+  scheduler_->ResetDamageForTest();
+  SubmitCompositorFrame(&pass_list, local_surface_id);
+
+  display_->DrawAndSwap();
+
+  // This is the same as LatencyInfo::kMaxLatencyInfoNumber.
+  const size_t max_latency_info_count = 100;
+  for (size_t i = 0; i <= max_latency_info_count; ++i) {
+    pass = cc::RenderPass::Create();
+    pass->output_rect = gfx::Rect(0, 0, 100, 100);
+    pass->damage_rect = gfx::Rect(10, 10, 0, 0);
+    pass->id = 1u;
+
+    pass_list.push_back(std::move(pass));
+    scheduler_->ResetDamageForTest();
+
+    cc::CompositorFrame frame = cc::test::MakeCompositorFrame();
+    pass_list.swap(frame.render_pass_list);
+    frame.metadata.latency_info.push_back(ui::LatencyInfo());
+
+    support_->SubmitCompositorFrame(local_surface_id, std::move(frame));
+
+    display_->DrawAndSwap();
+
+    if (i < max_latency_info_count)
+      EXPECT_EQ(i + 1, display_->stored_latency_info_size_for_testing());
+    else
+      EXPECT_EQ(0u, display_->stored_latency_info_size_for_testing());
+  }
+
+  TearDownDisplay();
+}
+
+class MockedContext : public cc::TestWebGraphicsContext3D {
+ public:
+  MOCK_METHOD0(shallowFinishCHROMIUM, void());
+};
+
+TEST_F(DisplayTest, Finish) {
+  LocalSurfaceId local_surface_id1(id_allocator_.GenerateId());
+  LocalSurfaceId local_surface_id2(id_allocator_.GenerateId());
+
+  cc::RendererSettings settings;
+  settings.partial_swap_enabled = true;
+  settings.finish_rendering_on_resize = true;
+
+  auto context = base::MakeUnique<MockedContext>();
+  MockedContext* context_ptr = context.get();
+  EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM()).Times(0);
+
+  SetUpDisplay(settings, std::move(context));
+
+  StubDisplayClient client;
+  display_->Initialize(&client, manager_.surface_manager());
+
+  display_->SetLocalSurfaceId(local_surface_id1, 1.f);
+
+  display_->Resize(gfx::Size(100, 100));
+
+  {
+    cc::RenderPassList pass_list;
+    auto pass = cc::RenderPass::Create();
+    pass->output_rect = gfx::Rect(0, 0, 100, 100);
+    pass->damage_rect = gfx::Rect(10, 10, 1, 1);
+    pass->id = 1u;
+    pass_list.push_back(std::move(pass));
+
+    SubmitCompositorFrame(&pass_list, local_surface_id1);
+  }
+
+  display_->DrawAndSwap();
+
+  // First resize and draw shouldn't finish.
+  testing::Mock::VerifyAndClearExpectations(context_ptr);
+
+  EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM());
+  display_->Resize(gfx::Size(150, 150));
+  testing::Mock::VerifyAndClearExpectations(context_ptr);
+
+  // Another resize without a swap doesn't need to finish.
+  EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM()).Times(0);
+  display_->SetLocalSurfaceId(local_surface_id2, 1.f);
+  display_->Resize(gfx::Size(200, 200));
+  testing::Mock::VerifyAndClearExpectations(context_ptr);
+
+  EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM()).Times(0);
+  {
+    cc::RenderPassList pass_list;
+    auto pass = cc::RenderPass::Create();
+    pass->output_rect = gfx::Rect(0, 0, 200, 200);
+    pass->damage_rect = gfx::Rect(10, 10, 1, 1);
+    pass->id = 1u;
+    pass_list.push_back(std::move(pass));
+
+    SubmitCompositorFrame(&pass_list, local_surface_id2);
+  }
+
+  display_->DrawAndSwap();
+
+  testing::Mock::VerifyAndClearExpectations(context_ptr);
+
+  EXPECT_CALL(*context_ptr, shallowFinishCHROMIUM());
+  display_->Resize(gfx::Size(250, 250));
+  testing::Mock::VerifyAndClearExpectations(context_ptr);
+  TearDownDisplay();
+}
+
+class CountLossDisplayClient : public StubDisplayClient {
+ public:
+  CountLossDisplayClient() = default;
+
+  void DisplayOutputSurfaceLost() override { ++loss_count_; }
+
+  int loss_count() const { return loss_count_; }
+
+ private:
+  int loss_count_ = 0;
+};
+
+TEST_F(DisplayTest, ContextLossInformsClient) {
+  SetUpDisplay(cc::RendererSettings(), cc::TestWebGraphicsContext3D::Create());
+
+  CountLossDisplayClient client;
+  display_->Initialize(&client, manager_.surface_manager());
+
+  // Verify DidLoseOutputSurface callback is hooked up correctly.
+  EXPECT_EQ(0, client.loss_count());
+  output_surface_->context_provider()->ContextGL()->LoseContextCHROMIUM(
+      GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB);
+  output_surface_->context_provider()->ContextGL()->Flush();
+  EXPECT_EQ(1, client.loss_count());
+  TearDownDisplay();
+}
+
+// Regression test for https://crbug.com/727162: Submitting a CompositorFrame to
+// a surface should only cause damage on the Display the surface belongs to.
+// There should not be a side-effect on other Displays.
+TEST_F(DisplayTest, CompositorFrameDamagesCorrectDisplay) {
+  cc::RendererSettings settings;
+  LocalSurfaceId local_surface_id(id_allocator_.GenerateId());
+
+  // Set up first display.
+  SetUpDisplay(settings, nullptr);
+  StubDisplayClient client;
+  display_->Initialize(&client, manager_.surface_manager());
+  display_->SetLocalSurfaceId(local_surface_id, 1.f);
+
+  // Set up second frame sink + display.
+  auto support2 = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kAnotherFrameSinkId, true /* is_root */,
+      true /* handles_frame_sink_id_invalidation */,
+      true /* needs_sync_points */);
+  auto begin_frame_source2 = base::MakeUnique<cc::StubBeginFrameSource>();
+  auto scheduler_for_display2 = base::MakeUnique<TestDisplayScheduler>(
+      begin_frame_source2.get(), task_runner_.get());
+  TestDisplayScheduler* scheduler2 = scheduler_for_display2.get();
+  auto display2 = CreateDisplay(
+      settings, kAnotherFrameSinkId, std::move(scheduler_for_display2),
+      cc::FakeOutputSurface::CreateSoftware(
+          base::MakeUnique<TestSoftwareOutputDevice>()));
+  manager_.RegisterBeginFrameSource(begin_frame_source2.get(),
+                                    kAnotherFrameSinkId);
+  StubDisplayClient client2;
+  display2->Initialize(&client2, manager_.surface_manager());
+  display2->SetLocalSurfaceId(local_surface_id, 1.f);
+
+  display_->Resize(gfx::Size(100, 100));
+  display2->Resize(gfx::Size(100, 100));
+
+  scheduler_->ResetDamageForTest();
+  scheduler2->ResetDamageForTest();
+  EXPECT_FALSE(scheduler_->damaged);
+  EXPECT_FALSE(scheduler2->damaged);
+
+  // Submit a frame for display_ with full damage.
+  cc::RenderPassList pass_list;
+  auto pass = cc::RenderPass::Create();
+  pass->output_rect = gfx::Rect(0, 0, 100, 100);
+  pass->damage_rect = gfx::Rect(10, 10, 1, 1);
+  pass->id = 1;
+  pass_list.push_back(std::move(pass));
+
+  SubmitCompositorFrame(&pass_list, local_surface_id);
+
+  // Should have damaged only display_ but not display2.
+  EXPECT_TRUE(scheduler_->damaged);
+  EXPECT_FALSE(scheduler2->damaged);
+  manager_.UnregisterBeginFrameSource(begin_frame_source2.get());
+  TearDownDisplay();
+}
+
+}  // namespace
+}  // namespace viz
diff --git a/components/viz/service/display/surface_aggregator.cc b/components/viz/service/display/surface_aggregator.cc
new file mode 100644
index 0000000..4e1698d
--- /dev/null
+++ b/components/viz/service/display/surface_aggregator.cc
@@ -0,0 +1,942 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/display/surface_aggregator.h"
+
+#include <stddef.h>
+
+#include <map>
+
+#include "base/bind.h"
+#include "base/containers/adapters.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
+#include "base/stl_util.h"
+#include "base/trace_event/trace_event.h"
+#include "cc/base/math_util.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/quads/draw_quad.h"
+#include "cc/quads/render_pass_draw_quad.h"
+#include "cc/quads/shared_quad_state.h"
+#include "cc/quads/solid_color_draw_quad.h"
+#include "cc/quads/surface_draw_quad.h"
+#include "cc/quads/texture_draw_quad.h"
+#include "cc/resources/resource_provider.h"
+#include "cc/surfaces/surface.h"
+#include "cc/surfaces/surface_client.h"
+#include "cc/surfaces/surface_manager.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
+
+namespace viz {
+namespace {
+
+// Maximum bucket size for the UMA stats.
+constexpr int kUmaStatMaxSurfaces = 30;
+
+const char kUmaValidSurface[] =
+    "Compositing.SurfaceAggregator.SurfaceDrawQuad.ValidSurface";
+const char kUmaMissingSurface[] =
+    "Compositing.SurfaceAggregator.SurfaceDrawQuad.MissingSurface";
+const char kUmaNoActiveFrame[] =
+    "Compositing.SurfaceAggregator.SurfaceDrawQuad.NoActiveFrame";
+
+void MoveMatchingRequests(
+    cc::RenderPassId render_pass_id,
+    std::multimap<cc::RenderPassId, std::unique_ptr<cc::CopyOutputRequest>>*
+        copy_requests,
+    std::vector<std::unique_ptr<cc::CopyOutputRequest>>* output_requests) {
+  auto request_range = copy_requests->equal_range(render_pass_id);
+  for (auto it = request_range.first; it != request_range.second; ++it) {
+    DCHECK(it->second);
+    output_requests->push_back(std::move(it->second));
+  }
+  copy_requests->erase(request_range.first, request_range.second);
+}
+
+// Returns true if the damage rect is valid.
+bool CalculateQuadSpaceDamageRect(
+    const gfx::Transform& quad_to_target_transform,
+    const gfx::Transform& target_to_root_transform,
+    const gfx::Rect& root_damage_rect,
+    gfx::Rect* quad_space_damage_rect) {
+  gfx::Transform quad_to_root_transform(target_to_root_transform,
+                                        quad_to_target_transform);
+  gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization);
+  bool inverse_valid = quad_to_root_transform.GetInverse(&inverse_transform);
+  if (!inverse_valid)
+    return false;
+
+  *quad_space_damage_rect = cc::MathUtil::ProjectEnclosingClippedRect(
+      inverse_transform, root_damage_rect);
+  return true;
+}
+
+}  // namespace
+
+SurfaceAggregator::SurfaceAggregator(cc::SurfaceManager* manager,
+                                     cc::ResourceProvider* provider,
+                                     bool aggregate_only_damaged)
+    : manager_(manager),
+      provider_(provider),
+      next_render_pass_id_(1),
+      aggregate_only_damaged_(aggregate_only_damaged),
+      weak_factory_(this) {
+  DCHECK(manager_);
+}
+
+SurfaceAggregator::~SurfaceAggregator() {
+  // Notify client of all surfaces being removed.
+  contained_surfaces_.clear();
+  ProcessAddedAndRemovedSurfaces();
+}
+
+SurfaceAggregator::PrewalkResult::PrewalkResult() {}
+
+SurfaceAggregator::PrewalkResult::~PrewalkResult() {}
+
+// Create a clip rect for an aggregated quad from the original clip rect and
+// the clip rect from the surface it's on.
+SurfaceAggregator::ClipData SurfaceAggregator::CalculateClipRect(
+    const ClipData& surface_clip,
+    const ClipData& quad_clip,
+    const gfx::Transform& target_transform) {
+  ClipData out_clip;
+  if (surface_clip.is_clipped)
+    out_clip = surface_clip;
+
+  if (quad_clip.is_clipped) {
+    // TODO(jamesr): This only works if target_transform maps integer
+    // rects to integer rects.
+    gfx::Rect final_clip =
+        cc::MathUtil::MapEnclosingClippedRect(target_transform, quad_clip.rect);
+    if (out_clip.is_clipped)
+      out_clip.rect.Intersect(final_clip);
+    else
+      out_clip.rect = final_clip;
+    out_clip.is_clipped = true;
+  }
+
+  return out_clip;
+}
+
+cc::RenderPassId SurfaceAggregator::RemapPassId(
+    cc::RenderPassId surface_local_pass_id,
+    const SurfaceId& surface_id) {
+  auto key = std::make_pair(surface_id, surface_local_pass_id);
+  auto it = render_pass_allocator_map_.find(key);
+  if (it != render_pass_allocator_map_.end()) {
+    it->second.in_use = true;
+    return it->second.id;
+  }
+
+  RenderPassInfo render_pass_info;
+  render_pass_info.id = next_render_pass_id_++;
+  render_pass_allocator_map_[key] = render_pass_info;
+  return render_pass_info.id;
+}
+
+int SurfaceAggregator::ChildIdForSurface(cc::Surface* surface) {
+  auto it = surface_id_to_resource_child_id_.find(surface->surface_id());
+  if (it == surface_id_to_resource_child_id_.end()) {
+    int child_id = provider_->CreateChild(
+        base::Bind(&SurfaceAggregator::UnrefResources, surface->client()));
+    provider_->SetChildNeedsSyncTokens(child_id, surface->needs_sync_tokens());
+    surface_id_to_resource_child_id_[surface->surface_id()] = child_id;
+    return child_id;
+  } else {
+    return it->second;
+  }
+}
+
+gfx::Rect SurfaceAggregator::DamageRectForSurface(
+    const cc::Surface* surface,
+    const cc::RenderPass& source,
+    const gfx::Rect& full_rect) const {
+  auto it = previous_contained_surfaces_.find(surface->surface_id());
+  if (it != previous_contained_surfaces_.end()) {
+    int previous_index = it->second;
+    if (previous_index == surface->frame_index())
+      return gfx::Rect();
+  }
+  const SurfaceId& previous_surface_id = surface->previous_frame_surface_id();
+
+  if (surface->surface_id() != previous_surface_id) {
+    it = previous_contained_surfaces_.find(previous_surface_id);
+  }
+  if (it != previous_contained_surfaces_.end()) {
+    int previous_index = it->second;
+    if (previous_index == surface->frame_index() - 1)
+      return source.damage_rect;
+  }
+
+  return full_rect;
+}
+
+// static
+void SurfaceAggregator::UnrefResources(
+    base::WeakPtr<cc::SurfaceClient> surface_client,
+    const std::vector<cc::ReturnedResource>& resources,
+    cc::BlockingTaskRunner* main_thread_task_runner) {
+  if (surface_client)
+    surface_client->UnrefResources(resources);
+}
+
+void SurfaceAggregator::HandleSurfaceQuad(
+    const cc::SurfaceDrawQuad* surface_quad,
+    const gfx::Transform& target_transform,
+    const ClipData& clip_rect,
+    cc::RenderPass* dest_pass,
+    bool ignore_undamaged,
+    gfx::Rect* damage_rect_in_quad_space,
+    bool* damage_rect_in_quad_space_valid) {
+  SurfaceId surface_id = surface_quad->surface_id;
+  // If this surface's id is already in our referenced set then it creates
+  // a cycle in the graph and should be dropped.
+  if (referenced_surfaces_.count(surface_id))
+    return;
+  cc::Surface* surface = manager_->GetSurfaceForId(surface_id);
+  if (!surface || !surface->HasActiveFrame()) {
+    if (surface_quad->fallback_quad) {
+      HandleSurfaceQuad(surface_quad->fallback_quad, target_transform,
+                        clip_rect, dest_pass, ignore_undamaged,
+                        damage_rect_in_quad_space,
+                        damage_rect_in_quad_space_valid);
+    } else if (!surface) {
+      ++uma_stats_.missing_surface;
+    } else {
+      ++uma_stats_.no_active_frame;
+    }
+    return;
+  }
+  ++uma_stats_.valid_surface;
+
+  if (ignore_undamaged) {
+    gfx::Transform quad_to_target_transform(
+        target_transform,
+        surface_quad->shared_quad_state->quad_to_target_transform);
+    *damage_rect_in_quad_space_valid = CalculateQuadSpaceDamageRect(
+        quad_to_target_transform, dest_pass->transform_to_root_target,
+        root_damage_rect_, damage_rect_in_quad_space);
+    if (*damage_rect_in_quad_space_valid &&
+        !damage_rect_in_quad_space->Intersects(surface_quad->visible_rect)) {
+      return;
+    }
+  }
+
+  const cc::CompositorFrame& frame = surface->GetActiveFrame();
+
+  // A map keyed by RenderPass id.
+  cc::Surface::CopyRequestsMap copy_requests;
+  surface->TakeCopyOutputRequests(&copy_requests);
+
+  const cc::RenderPassList& render_pass_list = frame.render_pass_list;
+  if (!valid_surfaces_.count(surface->surface_id())) {
+    for (auto& request : copy_requests)
+      request.second->SendEmptyResult();
+    return;
+  }
+
+  referenced_surfaces_.insert(surface_id);
+  // TODO(vmpstr): provider check is a hack for unittests that don't set up a
+  // resource provider.
+  cc::ResourceProvider::ResourceIdMap empty_map;
+  const auto& child_to_parent_map =
+      provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface))
+                : empty_map;
+  bool merge_pass =
+      surface_quad->shared_quad_state->opacity == 1.f && copy_requests.empty();
+
+  const cc::RenderPassList& referenced_passes = render_pass_list;
+  size_t passes_to_copy =
+      merge_pass ? referenced_passes.size() - 1 : referenced_passes.size();
+  for (size_t j = 0; j < passes_to_copy; ++j) {
+    const cc::RenderPass& source = *referenced_passes[j];
+
+    size_t sqs_size = source.shared_quad_state_list.size();
+    size_t dq_size = source.quad_list.size();
+    std::unique_ptr<cc::RenderPass> copy_pass(
+        cc::RenderPass::Create(sqs_size, dq_size));
+
+    cc::RenderPassId remapped_pass_id = RemapPassId(source.id, surface_id);
+
+    copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect,
+                      source.transform_to_root_target, source.filters,
+                      source.background_filters, blending_color_space_,
+                      source.has_transparent_background);
+
+    MoveMatchingRequests(source.id, &copy_requests, &copy_pass->copy_requests);
+
+    // Contributing passes aggregated in to the pass list need to take the
+    // transform of the surface quad into account to update their transform to
+    // the root surface.
+    copy_pass->transform_to_root_target.ConcatTransform(
+        surface_quad->shared_quad_state->quad_to_target_transform);
+    copy_pass->transform_to_root_target.ConcatTransform(target_transform);
+    copy_pass->transform_to_root_target.ConcatTransform(
+        dest_pass->transform_to_root_target);
+
+    CopyQuadsToPass(source.quad_list, source.shared_quad_state_list,
+                    child_to_parent_map, gfx::Transform(), ClipData(),
+                    copy_pass.get(), surface_id);
+
+    if (!copy_request_passes_.count(remapped_pass_id) &&
+        !moved_pixel_passes_.count(remapped_pass_id)) {
+      gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization);
+      if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) {
+        gfx::Rect damage_rect_in_render_pass_space =
+            cc::MathUtil::ProjectEnclosingClippedRect(inverse_transform,
+                                                      root_damage_rect_);
+        copy_pass->damage_rect.Intersect(damage_rect_in_render_pass_space);
+      }
+    }
+
+    dest_pass_list_->push_back(std::move(copy_pass));
+  }
+
+  gfx::Transform surface_transform =
+      surface_quad->shared_quad_state->quad_to_target_transform;
+  surface_transform.ConcatTransform(target_transform);
+
+  const auto& last_pass = *render_pass_list.back();
+  if (merge_pass) {
+    // TODO(jamesr): Clean up last pass special casing.
+    const cc::QuadList& quads = last_pass.quad_list;
+
+    // Intersect the transformed visible rect and the clip rect to create a
+    // smaller cliprect for the quad.
+    ClipData surface_quad_clip_rect(
+        true, cc::MathUtil::MapEnclosingClippedRect(
+                  surface_quad->shared_quad_state->quad_to_target_transform,
+                  surface_quad->visible_rect));
+    if (surface_quad->shared_quad_state->is_clipped) {
+      surface_quad_clip_rect.rect.Intersect(
+          surface_quad->shared_quad_state->clip_rect);
+    }
+
+    ClipData quads_clip =
+        CalculateClipRect(clip_rect, surface_quad_clip_rect, target_transform);
+
+    CopyQuadsToPass(quads, last_pass.shared_quad_state_list,
+                    child_to_parent_map, surface_transform, quads_clip,
+                    dest_pass, surface_id);
+  } else {
+    cc::RenderPassId remapped_pass_id = RemapPassId(last_pass.id, surface_id);
+
+    auto* shared_quad_state =
+        CopySharedQuadState(surface_quad->shared_quad_state, target_transform,
+                            clip_rect, dest_pass);
+
+    auto* quad = dest_pass->CreateAndAppendDrawQuad<cc::RenderPassDrawQuad>();
+    quad->SetNew(shared_quad_state, surface_quad->rect,
+                 surface_quad->visible_rect, remapped_pass_id, 0, gfx::RectF(),
+                 gfx::Size(), gfx::Vector2dF(), gfx::PointF(),
+                 gfx::RectF(surface_quad->rect));
+  }
+
+  // Need to re-query since referenced_surfaces_ iterators are not stable.
+  referenced_surfaces_.erase(referenced_surfaces_.find(surface_id));
+}
+
+void SurfaceAggregator::AddColorConversionPass() {
+  if (dest_pass_list_->empty())
+    return;
+
+  auto* root_render_pass = dest_pass_list_->back().get();
+  if (root_render_pass->color_space == output_color_space_)
+    return;
+
+  gfx::Rect output_rect = root_render_pass->output_rect;
+  CHECK(root_render_pass->transform_to_root_target == gfx::Transform());
+
+  if (!color_conversion_render_pass_id_)
+    color_conversion_render_pass_id_ = next_render_pass_id_++;
+
+  auto color_conversion_pass = cc::RenderPass::Create(1, 1);
+  color_conversion_pass->SetNew(color_conversion_render_pass_id_, output_rect,
+                                root_render_pass->damage_rect,
+                                root_render_pass->transform_to_root_target);
+  color_conversion_pass->color_space = output_color_space_;
+
+  auto* shared_quad_state =
+      color_conversion_pass->CreateAndAppendSharedQuadState();
+  shared_quad_state->quad_layer_rect = output_rect;
+  shared_quad_state->visible_quad_layer_rect = output_rect;
+  shared_quad_state->opacity = 1.f;
+
+  auto* quad =
+      color_conversion_pass->CreateAndAppendDrawQuad<cc::RenderPassDrawQuad>();
+  quad->SetNew(shared_quad_state, output_rect, output_rect,
+               root_render_pass->id, 0, gfx::RectF(), gfx::Size(),
+               gfx::Vector2dF(), gfx::PointF(), gfx::RectF(output_rect));
+  dest_pass_list_->push_back(std::move(color_conversion_pass));
+}
+
+cc::SharedQuadState* SurfaceAggregator::CopySharedQuadState(
+    const cc::SharedQuadState* source_sqs,
+    const gfx::Transform& target_transform,
+    const ClipData& clip_rect,
+    cc::RenderPass* dest_render_pass) {
+  auto* copy_shared_quad_state =
+      dest_render_pass->CreateAndAppendSharedQuadState();
+  *copy_shared_quad_state = *source_sqs;
+  // target_transform contains any transformation that may exist
+  // between the context that these quads are being copied from (i.e. the
+  // surface's draw transform when aggregated from within a surface) to the
+  // target space of the pass. This will be identity except when copying the
+  // root draw pass from a surface into a pass when the surface draw quad's
+  // transform is not identity.
+  copy_shared_quad_state->quad_to_target_transform.ConcatTransform(
+      target_transform);
+
+  ClipData new_clip_rect = CalculateClipRect(
+      clip_rect, ClipData(source_sqs->is_clipped, source_sqs->clip_rect),
+      target_transform);
+  copy_shared_quad_state->is_clipped = new_clip_rect.is_clipped;
+  copy_shared_quad_state->clip_rect = new_clip_rect.rect;
+  return copy_shared_quad_state;
+}
+
+void SurfaceAggregator::CopyQuadsToPass(
+    const cc::QuadList& source_quad_list,
+    const cc::SharedQuadStateList& source_shared_quad_state_list,
+    const std::unordered_map<cc::ResourceId, cc::ResourceId>&
+        child_to_parent_map,
+    const gfx::Transform& target_transform,
+    const ClipData& clip_rect,
+    cc::RenderPass* dest_pass,
+    const SurfaceId& surface_id) {
+  const cc::SharedQuadState* last_copied_source_shared_quad_state = nullptr;
+  const cc::SharedQuadState* dest_shared_quad_state = nullptr;
+  // If the current frame has copy requests then aggregate the entire
+  // thing, as otherwise parts of the copy requests may be ignored.
+  const bool ignore_undamaged = aggregate_only_damaged_ &&
+                                !has_copy_requests_ &&
+                                !moved_pixel_passes_.count(dest_pass->id);
+  // Damage rect in the quad space of the current shared quad state.
+  // TODO(jbauman): This rect may contain unnecessary area if
+  // transform isn't axis-aligned.
+  gfx::Rect damage_rect_in_quad_space;
+  bool damage_rect_in_quad_space_valid = false;
+
+#if DCHECK_IS_ON()
+  // If quads have come in with SharedQuadState out of order, or when quads have
+  // invalid SharedQuadState pointer, it should DCHECK.
+  auto sqs_iter = source_shared_quad_state_list.cbegin();
+  for (auto* quad : source_quad_list) {
+    while (sqs_iter != source_shared_quad_state_list.cend() &&
+           quad->shared_quad_state != *sqs_iter) {
+      ++sqs_iter;
+    }
+    DCHECK(sqs_iter != source_shared_quad_state_list.cend());
+  }
+#endif
+
+  for (auto* quad : source_quad_list) {
+    if (quad->material == cc::DrawQuad::SURFACE_CONTENT) {
+      const auto* surface_quad = cc::SurfaceDrawQuad::MaterialCast(quad);
+      // HandleSurfaceQuad may add other shared quad state, so reset the
+      // current data.
+      last_copied_source_shared_quad_state = nullptr;
+
+      // The primary SurfaceDrawQuad should have already dealt with the fallback
+      // DrawQuad.
+      if (surface_quad->surface_draw_quad_type ==
+          cc::SurfaceDrawQuadType::FALLBACK)
+        continue;
+
+      HandleSurfaceQuad(surface_quad, target_transform, clip_rect, dest_pass,
+                        ignore_undamaged, &damage_rect_in_quad_space,
+                        &damage_rect_in_quad_space_valid);
+    } else {
+      if (quad->shared_quad_state != last_copied_source_shared_quad_state) {
+        dest_shared_quad_state = CopySharedQuadState(
+            quad->shared_quad_state, target_transform, clip_rect, dest_pass);
+        last_copied_source_shared_quad_state = quad->shared_quad_state;
+        if (aggregate_only_damaged_ && !has_copy_requests_) {
+          damage_rect_in_quad_space_valid = CalculateQuadSpaceDamageRect(
+              dest_shared_quad_state->quad_to_target_transform,
+              dest_pass->transform_to_root_target, root_damage_rect_,
+              &damage_rect_in_quad_space);
+        }
+      }
+
+      if (ignore_undamaged) {
+        if (damage_rect_in_quad_space_valid &&
+            !damage_rect_in_quad_space.Intersects(quad->visible_rect))
+          continue;
+      }
+
+      cc::DrawQuad* dest_quad;
+      if (quad->material == cc::DrawQuad::RENDER_PASS) {
+        const auto* pass_quad = cc::RenderPassDrawQuad::MaterialCast(quad);
+        int original_pass_id = pass_quad->render_pass_id;
+        int remapped_pass_id = RemapPassId(original_pass_id, surface_id);
+
+        dest_quad = dest_pass->CopyFromAndAppendRenderPassDrawQuad(
+            pass_quad, dest_shared_quad_state, remapped_pass_id);
+      } else if (quad->material == cc::DrawQuad::TEXTURE_CONTENT) {
+        const auto* texture_quad = cc::TextureDrawQuad::MaterialCast(quad);
+        if (texture_quad->secure_output_only &&
+            (!output_is_secure_ || copy_request_passes_.count(dest_pass->id))) {
+          auto* solid_color_quad =
+              dest_pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
+          solid_color_quad->SetNew(dest_shared_quad_state, quad->rect,
+                                   quad->visible_rect, SK_ColorBLACK, false);
+          dest_quad = solid_color_quad;
+        } else {
+          dest_quad = dest_pass->CopyFromAndAppendDrawQuad(
+              quad, dest_shared_quad_state);
+        }
+      } else {
+        dest_quad =
+            dest_pass->CopyFromAndAppendDrawQuad(quad, dest_shared_quad_state);
+      }
+      if (!child_to_parent_map.empty()) {
+        for (cc::ResourceId& resource_id : dest_quad->resources) {
+          auto it = child_to_parent_map.find(resource_id);
+          DCHECK(it != child_to_parent_map.end());
+
+          DCHECK_EQ(it->first, resource_id);
+          cc::ResourceId remapped_id = it->second;
+          resource_id = remapped_id;
+        }
+      }
+    }
+  }
+}
+
+void SurfaceAggregator::CopyPasses(const cc::CompositorFrame& frame,
+                                   cc::Surface* surface) {
+  // The root surface is allowed to have copy output requests, so grab them
+  // off its render passes. This map contains a set of CopyOutputRequests
+  // keyed by each RenderPass id.
+  cc::Surface::CopyRequestsMap copy_requests;
+  surface->TakeCopyOutputRequests(&copy_requests);
+
+  const auto& source_pass_list = frame.render_pass_list;
+  DCHECK(valid_surfaces_.count(surface->surface_id()));
+  if (!valid_surfaces_.count(surface->surface_id()))
+    return;
+
+  // TODO(vmpstr): provider check is a hack for unittests that don't set up a
+  // resource provider.
+  cc::ResourceProvider::ResourceIdMap empty_map;
+  const auto& child_to_parent_map =
+      provider_ ? provider_->GetChildToParentMap(ChildIdForSurface(surface))
+                : empty_map;
+  for (size_t i = 0; i < source_pass_list.size(); ++i) {
+    const auto& source = *source_pass_list[i];
+
+    size_t sqs_size = source.shared_quad_state_list.size();
+    size_t dq_size = source.quad_list.size();
+    auto copy_pass = cc::RenderPass::Create(sqs_size, dq_size);
+
+    MoveMatchingRequests(source.id, &copy_requests, &copy_pass->copy_requests);
+
+    cc::RenderPassId remapped_pass_id =
+        RemapPassId(source.id, surface->surface_id());
+
+    copy_pass->SetAll(remapped_pass_id, source.output_rect, source.output_rect,
+                      source.transform_to_root_target, source.filters,
+                      source.background_filters, blending_color_space_,
+                      source.has_transparent_background);
+
+    CopyQuadsToPass(source.quad_list, source.shared_quad_state_list,
+                    child_to_parent_map, gfx::Transform(), ClipData(),
+                    copy_pass.get(), surface->surface_id());
+    if (!copy_request_passes_.count(remapped_pass_id) &&
+        !moved_pixel_passes_.count(remapped_pass_id)) {
+      gfx::Transform inverse_transform(gfx::Transform::kSkipInitialization);
+      if (copy_pass->transform_to_root_target.GetInverse(&inverse_transform)) {
+        gfx::Rect damage_rect_in_render_pass_space =
+            cc::MathUtil::ProjectEnclosingClippedRect(inverse_transform,
+                                                      root_damage_rect_);
+        copy_pass->damage_rect.Intersect(damage_rect_in_render_pass_space);
+      }
+    }
+
+    dest_pass_list_->push_back(std::move(copy_pass));
+  }
+}
+
+void SurfaceAggregator::ProcessAddedAndRemovedSurfaces() {
+  for (const auto& surface : previous_contained_surfaces_) {
+    if (!contained_surfaces_.count(surface.first)) {
+      // Release resources of removed surface.
+      auto it = surface_id_to_resource_child_id_.find(surface.first);
+      if (it != surface_id_to_resource_child_id_.end()) {
+        provider_->DestroyChild(it->second);
+        surface_id_to_resource_child_id_.erase(it);
+      }
+
+      // Notify client of removed surface.
+      cc::Surface* surface_ptr = manager_->GetSurfaceForId(surface.first);
+      if (surface_ptr) {
+        surface_ptr->RunDrawCallback();
+      }
+    }
+  }
+}
+
+// Walk the Surface tree from surface_id. Validate the resources of the current
+// surface and its descendants, check if there are any copy requests, and
+// return the combined damage rect.
+gfx::Rect SurfaceAggregator::PrewalkTree(const SurfaceId& surface_id,
+                                         bool in_moved_pixel_surface,
+                                         int parent_pass_id,
+                                         PrewalkResult* result) {
+  // This is for debugging a possible use after free.
+  // TODO(jbauman): Remove this once we have enough information.
+  // http://crbug.com/560181
+  base::WeakPtr<SurfaceAggregator> debug_weak_this = weak_factory_.GetWeakPtr();
+
+  if (referenced_surfaces_.count(surface_id))
+    return gfx::Rect();
+  cc::Surface* surface = manager_->GetSurfaceForId(surface_id);
+  if (!surface) {
+    contained_surfaces_[surface_id] = 0;
+    return gfx::Rect();
+  }
+  contained_surfaces_[surface_id] = surface->frame_index();
+  if (!surface->HasActiveFrame())
+    return gfx::Rect();
+  const cc::CompositorFrame& frame = surface->GetActiveFrame();
+  int child_id = 0;
+  // TODO(jbauman): hack for unit tests that don't set up rp
+  if (provider_) {
+    child_id = ChildIdForSurface(surface);
+    surface->RefResources(frame.resource_list);
+    provider_->ReceiveFromChild(child_id, frame.resource_list);
+  }
+  CHECK(debug_weak_this.get());
+
+  std::vector<cc::ResourceId> referenced_resources;
+  size_t reserve_size = frame.resource_list.size();
+  referenced_resources.reserve(reserve_size);
+
+  bool invalid_frame = false;
+  cc::ResourceProvider::ResourceIdMap empty_map;
+  const auto& child_to_parent_map =
+      provider_ ? provider_->GetChildToParentMap(child_id) : empty_map;
+
+  CHECK(debug_weak_this.get());
+  cc::RenderPassId remapped_pass_id =
+      RemapPassId(frame.render_pass_list.back()->id, surface_id);
+  if (in_moved_pixel_surface)
+    moved_pixel_passes_.insert(remapped_pass_id);
+  if (parent_pass_id)
+    render_pass_dependencies_[parent_pass_id].insert(remapped_pass_id);
+
+  struct SurfaceInfo {
+    SurfaceInfo(const SurfaceId& id,
+                bool has_moved_pixels,
+                cc::RenderPassId parent_pass_id,
+                const gfx::Transform& target_to_surface_transform)
+        : id(id),
+          has_moved_pixels(has_moved_pixels),
+          parent_pass_id(parent_pass_id),
+          target_to_surface_transform(target_to_surface_transform) {}
+
+    SurfaceId id;
+    bool has_moved_pixels;
+    cc::RenderPassId parent_pass_id;
+    gfx::Transform target_to_surface_transform;
+  };
+  std::vector<SurfaceInfo> child_surfaces;
+
+  // This data is created once and typically small or empty. Collect all items
+  // and pass to a flat_vector to sort once.
+  std::vector<cc::RenderPassId> pixel_moving_background_filter_passes_data;
+  for (const auto& render_pass : frame.render_pass_list) {
+    if (render_pass->background_filters.HasFilterThatMovesPixels()) {
+      pixel_moving_background_filter_passes_data.push_back(
+          RemapPassId(render_pass->id, surface_id));
+    }
+  }
+  base::flat_set<cc::RenderPassId> pixel_moving_background_filter_passes(
+      std::move(pixel_moving_background_filter_passes_data),
+      base::KEEP_FIRST_OF_DUPES);
+
+  for (const auto& render_pass : base::Reversed(frame.render_pass_list)) {
+    cc::RenderPassId remapped_pass_id =
+        RemapPassId(render_pass->id, surface_id);
+    bool has_pixel_moving_filter =
+        render_pass->filters.HasFilterThatMovesPixels();
+    if (has_pixel_moving_filter)
+      moved_pixel_passes_.insert(remapped_pass_id);
+    bool in_moved_pixel_pass = has_pixel_moving_filter ||
+                               !!moved_pixel_passes_.count(remapped_pass_id);
+    for (auto* quad : render_pass->quad_list) {
+      if (quad->material == cc::DrawQuad::SURFACE_CONTENT) {
+        const auto* surface_quad = cc::SurfaceDrawQuad::MaterialCast(quad);
+        gfx::Transform target_to_surface_transform(
+            render_pass->transform_to_root_target,
+            surface_quad->shared_quad_state->quad_to_target_transform);
+        child_surfaces.emplace_back(surface_quad->surface_id,
+                                    in_moved_pixel_pass, remapped_pass_id,
+                                    target_to_surface_transform);
+      } else if (quad->material == cc::DrawQuad::RENDER_PASS) {
+        const auto* render_pass_quad =
+            cc::RenderPassDrawQuad::MaterialCast(quad);
+        if (in_moved_pixel_pass) {
+          moved_pixel_passes_.insert(
+              RemapPassId(render_pass_quad->render_pass_id, surface_id));
+        }
+        if (pixel_moving_background_filter_passes.count(
+                render_pass_quad->render_pass_id)) {
+          in_moved_pixel_pass = true;
+        }
+        render_pass_dependencies_[remapped_pass_id].insert(
+            RemapPassId(render_pass_quad->render_pass_id, surface_id));
+      }
+
+      if (!provider_)
+        continue;
+      for (cc::ResourceId resource_id : quad->resources) {
+        if (!child_to_parent_map.count(resource_id)) {
+          invalid_frame = true;
+          break;
+        }
+        referenced_resources.push_back(resource_id);
+      }
+    }
+  }
+
+  if (invalid_frame)
+    return gfx::Rect();
+  CHECK(debug_weak_this.get());
+  valid_surfaces_.insert(surface->surface_id());
+
+  cc::ResourceIdSet resource_set(std::move(referenced_resources),
+                                 base::KEEP_FIRST_OF_DUPES);
+  if (provider_)
+    provider_->DeclareUsedResourcesFromChild(child_id, resource_set);
+  CHECK(debug_weak_this.get());
+
+  gfx::Rect damage_rect;
+  gfx::Rect full_damage;
+  cc::RenderPass* last_pass = frame.render_pass_list.back().get();
+  full_damage = last_pass->output_rect;
+  damage_rect =
+      DamageRectForSurface(surface, *last_pass, last_pass->output_rect);
+
+  // Avoid infinite recursion by adding current surface to
+  // referenced_surfaces_.
+  referenced_surfaces_.insert(surface->surface_id());
+  for (const auto& surface_info : child_surfaces) {
+    gfx::Rect surface_damage =
+        PrewalkTree(surface_info.id, surface_info.has_moved_pixels,
+                    surface_info.parent_pass_id, result);
+    if (surface_damage.IsEmpty())
+      continue;
+    if (surface_info.has_moved_pixels) {
+      // Areas outside the rect hit by target_to_surface_transform may be
+      // modified if there is a filter that moves pixels.
+      damage_rect = full_damage;
+      continue;
+    }
+
+    damage_rect.Union(cc::MathUtil::MapEnclosingClippedRect(
+        surface_info.target_to_surface_transform, surface_damage));
+  }
+
+  CHECK(debug_weak_this.get());
+  for (const auto& surface_id : frame.metadata.referenced_surfaces) {
+    if (!contained_surfaces_.count(surface_id)) {
+      result->undrawn_surfaces.insert(surface_id);
+      PrewalkTree(surface_id, false, 0, result);
+    }
+  }
+
+  CHECK(debug_weak_this.get());
+  // TODO(staraz): It shouldn't need to call the callback when the damage is
+  // from |surface| and not from |child_surfaces|.
+  if (!damage_rect.IsEmpty()) {
+    surface->RunWillDrawCallback(damage_rect);
+    manager_->SurfaceWillDraw(surface->surface_id());
+  }
+
+  CHECK(debug_weak_this.get());
+  for (const auto& render_pass : frame.render_pass_list) {
+    if (!render_pass->copy_requests.empty()) {
+      cc::RenderPassId remapped_pass_id =
+          RemapPassId(render_pass->id, surface_id);
+      copy_request_passes_.insert(remapped_pass_id);
+    }
+  }
+
+  referenced_surfaces_.erase(referenced_surfaces_.find(surface->surface_id()));
+  if (!damage_rect.IsEmpty() && frame.metadata.may_contain_video)
+    result->may_contain_video = true;
+  return damage_rect;
+}
+
+void SurfaceAggregator::CopyUndrawnSurfaces(PrewalkResult* prewalk_result) {
+  // undrawn_surfaces are Surfaces that were identified by prewalk as being
+  // referenced by a drawn Surface, but aren't contained in a SurfaceDrawQuad.
+  // They need to be iterated over to ensure that any copy requests on them
+  // (or on Surfaces they reference) are executed.
+  std::vector<SurfaceId> surfaces_to_copy(
+      prewalk_result->undrawn_surfaces.begin(),
+      prewalk_result->undrawn_surfaces.end());
+  DCHECK(referenced_surfaces_.empty());
+
+  for (size_t i = 0; i < surfaces_to_copy.size(); i++) {
+    SurfaceId surface_id = surfaces_to_copy[i];
+    cc::Surface* surface = manager_->GetSurfaceForId(surface_id);
+    if (!surface)
+      continue;
+    if (!surface->HasActiveFrame())
+      continue;
+    const cc::CompositorFrame& frame = surface->GetActiveFrame();
+    bool surface_has_copy_requests = false;
+    for (const auto& render_pass : frame.render_pass_list) {
+      surface_has_copy_requests |= !render_pass->copy_requests.empty();
+    }
+    if (!surface_has_copy_requests) {
+      // Children are not necessarily included in undrawn_surfaces (because
+      // they weren't referenced directly from a drawn surface), but may have
+      // copy requests, so make sure to check them as well.
+      for (const auto& child_id : frame.metadata.referenced_surfaces) {
+        // Don't iterate over the child Surface if it was already listed as a
+        // child of a different Surface, or in the case where there's infinite
+        // recursion.
+        if (!prewalk_result->undrawn_surfaces.count(child_id)) {
+          surfaces_to_copy.push_back(child_id);
+          prewalk_result->undrawn_surfaces.insert(child_id);
+        }
+      }
+    } else {
+      referenced_surfaces_.insert(surface_id);
+      CopyPasses(frame, surface);
+      // CopyPasses may have mutated container, need to re-query to erase.
+      referenced_surfaces_.erase(referenced_surfaces_.find(surface_id));
+    }
+  }
+}
+
+void SurfaceAggregator::PropagateCopyRequestPasses() {
+  std::vector<cc::RenderPassId> copy_requests_to_iterate(
+      copy_request_passes_.begin(), copy_request_passes_.end());
+  while (!copy_requests_to_iterate.empty()) {
+    int first = copy_requests_to_iterate.back();
+    copy_requests_to_iterate.pop_back();
+    auto it = render_pass_dependencies_.find(first);
+    if (it == render_pass_dependencies_.end())
+      continue;
+    for (auto pass : it->second) {
+      if (copy_request_passes_.insert(pass).second) {
+        copy_requests_to_iterate.push_back(pass);
+      }
+    }
+  }
+}
+
+cc::CompositorFrame SurfaceAggregator::Aggregate(const SurfaceId& surface_id) {
+  uma_stats_.Reset();
+
+  cc::Surface* surface = manager_->GetSurfaceForId(surface_id);
+  DCHECK(surface);
+  contained_surfaces_[surface_id] = surface->frame_index();
+
+  if (!surface->HasActiveFrame())
+    return {};
+
+  const cc::CompositorFrame& root_surface_frame = surface->GetActiveFrame();
+  TRACE_EVENT0("viz", "SurfaceAggregator::Aggregate");
+
+  cc::CompositorFrame frame;
+
+  dest_pass_list_ = &frame.render_pass_list;
+
+  valid_surfaces_.clear();
+  PrewalkResult prewalk_result;
+  root_damage_rect_ = PrewalkTree(surface_id, false, 0, &prewalk_result);
+  PropagateCopyRequestPasses();
+  has_copy_requests_ = !copy_request_passes_.empty();
+  frame.metadata.may_contain_video = prewalk_result.may_contain_video;
+
+  CopyUndrawnSurfaces(&prewalk_result);
+  referenced_surfaces_.insert(surface_id);
+  CopyPasses(root_surface_frame, surface);
+  // CopyPasses may have mutated container, need to re-query to erase.
+  referenced_surfaces_.erase(referenced_surfaces_.find(surface_id));
+  AddColorConversionPass();
+
+  moved_pixel_passes_.clear();
+  copy_request_passes_.clear();
+  render_pass_dependencies_.clear();
+
+  // Remove all render pass mappings that weren't used in the current frame.
+  for (auto it = render_pass_allocator_map_.begin();
+       it != render_pass_allocator_map_.end();) {
+    if (it->second.in_use) {
+      it->second.in_use = false;
+      it++;
+    } else {
+      it = render_pass_allocator_map_.erase(it);
+    }
+  }
+
+  DCHECK(referenced_surfaces_.empty());
+
+  if (dest_pass_list_->empty())
+    return {};
+
+  dest_pass_list_ = NULL;
+  ProcessAddedAndRemovedSurfaces();
+  contained_surfaces_.swap(previous_contained_surfaces_);
+  contained_surfaces_.clear();
+
+  for (auto it : previous_contained_surfaces_) {
+    cc::Surface* surface = manager_->GetSurfaceForId(it.first);
+    if (surface)
+      surface->TakeLatencyInfo(&frame.metadata.latency_info);
+  }
+
+  // TODO(jamesr): Aggregate all resource references into the returned frame's
+  // resource list.
+
+  // Log UMA stats for SurfaceDrawQuads on the number of surfaces that were
+  // aggregated together and any failures.
+  UMA_HISTOGRAM_EXACT_LINEAR(kUmaValidSurface, uma_stats_.valid_surface,
+                             kUmaStatMaxSurfaces);
+  UMA_HISTOGRAM_EXACT_LINEAR(kUmaMissingSurface, uma_stats_.missing_surface,
+                             kUmaStatMaxSurfaces);
+  UMA_HISTOGRAM_EXACT_LINEAR(kUmaNoActiveFrame, uma_stats_.no_active_frame,
+                             kUmaStatMaxSurfaces);
+
+  return frame;
+}
+
+void SurfaceAggregator::ReleaseResources(const SurfaceId& surface_id) {
+  auto it = surface_id_to_resource_child_id_.find(surface_id);
+  if (it != surface_id_to_resource_child_id_.end()) {
+    provider_->DestroyChild(it->second);
+    surface_id_to_resource_child_id_.erase(it);
+  }
+}
+
+void SurfaceAggregator::SetFullDamageForSurface(const SurfaceId& surface_id) {
+  auto it = previous_contained_surfaces_.find(surface_id);
+  if (it == previous_contained_surfaces_.end())
+    return;
+  // Set the last drawn index as 0 to ensure full damage next time it's drawn.
+  it->second = 0;
+}
+
+void SurfaceAggregator::SetOutputColorSpace(
+    const gfx::ColorSpace& blending_color_space,
+    const gfx::ColorSpace& output_color_space) {
+  blending_color_space_ = blending_color_space.IsValid()
+                              ? blending_color_space
+                              : gfx::ColorSpace::CreateSRGB();
+  output_color_space_ = output_color_space.IsValid()
+                            ? output_color_space
+                            : gfx::ColorSpace::CreateSRGB();
+}
+
+}  // namespace viz
diff --git a/components/viz/service/display/surface_aggregator.h b/components/viz/service/display/surface_aggregator.h
new file mode 100644
index 0000000..dfefbd4
--- /dev/null
+++ b/components/viz/service/display/surface_aggregator.h
@@ -0,0 +1,225 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_DISPLAY_SURFACE_AGGREGATOR_H_
+#define COMPONENTS_VIZ_SERVICE_DISPLAY_SURFACE_AGGREGATOR_H_
+
+#include <memory>
+#include <unordered_map>
+
+#include "base/containers/flat_map.h"
+#include "base/containers/flat_set.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "cc/quads/draw_quad.h"
+#include "cc/quads/render_pass.h"
+#include "cc/resources/transferable_resource.h"
+#include "components/viz/common/surface_id.h"
+#include "components/viz/service/viz_service_export.h"
+#include "ui/gfx/color_space.h"
+
+namespace cc {
+class BlockingTaskRunner;
+class CompositorFrame;
+class ResourceProvider;
+class Surface;
+class SurfaceClient;
+class SurfaceDrawQuad;
+class SurfaceManager;
+}  // namespace cc
+
+namespace viz {
+
+class VIZ_SERVICE_EXPORT SurfaceAggregator {
+ public:
+  using SurfaceIndexMap = base::flat_map<SurfaceId, int>;
+
+  SurfaceAggregator(cc::SurfaceManager* manager,
+                    cc::ResourceProvider* provider,
+                    bool aggregate_only_damaged);
+  ~SurfaceAggregator();
+
+  cc::CompositorFrame Aggregate(const SurfaceId& surface_id);
+  void ReleaseResources(const SurfaceId& surface_id);
+  SurfaceIndexMap& previous_contained_surfaces() {
+    return previous_contained_surfaces_;
+  }
+  void SetFullDamageForSurface(const SurfaceId& surface_id);
+  void set_output_is_secure(bool secure) { output_is_secure_ = secure; }
+
+  // Set the color spaces for the created RenderPasses, which is propagated
+  // to the output surface.
+  void SetOutputColorSpace(const gfx::ColorSpace& blending_color_space,
+                           const gfx::ColorSpace& output_color_space);
+
+ private:
+  struct ClipData {
+    ClipData() : is_clipped(false) {}
+    ClipData(bool is_clipped, const gfx::Rect& rect)
+        : is_clipped(is_clipped), rect(rect) {}
+
+    bool is_clipped;
+    gfx::Rect rect;
+  };
+
+  struct PrewalkResult {
+    PrewalkResult();
+    ~PrewalkResult();
+    // This is the set of Surfaces that were referenced by another Surface, but
+    // not included in a SurfaceDrawQuad.
+    base::flat_set<SurfaceId> undrawn_surfaces;
+    bool may_contain_video = false;
+  };
+
+  struct RenderPassInfo {
+    // This is the id the pass is mapped to.
+    int id;
+    // This is true if the pass was used in the last aggregated frame.
+    bool in_use = true;
+  };
+
+  struct SurfaceDrawQuadUmaStats {
+    void Reset() {
+      valid_surface = 0;
+      missing_surface = 0;
+      no_active_frame = 0;
+    }
+
+    // The surface exists and has an active frame.
+    int valid_surface;
+    // The surface doesn't exist.
+    int missing_surface;
+    // The surface exists but doesn't have an active frame.
+    int no_active_frame;
+  };
+
+  ClipData CalculateClipRect(const ClipData& surface_clip,
+                             const ClipData& quad_clip,
+                             const gfx::Transform& target_transform);
+
+  cc::RenderPassId RemapPassId(cc::RenderPassId surface_local_pass_id,
+                               const SurfaceId& surface_id);
+
+  void HandleSurfaceQuad(const cc::SurfaceDrawQuad* surface_quad,
+                         const gfx::Transform& target_transform,
+                         const ClipData& clip_rect,
+                         cc::RenderPass* dest_pass,
+                         bool ignore_undamaged,
+                         gfx::Rect* damage_rect_in_quad_space,
+                         bool* damage_rect_in_quad_space_valid);
+
+  cc::SharedQuadState* CopySharedQuadState(
+      const cc::SharedQuadState* source_sqs,
+      const gfx::Transform& target_transform,
+      const ClipData& clip_rect,
+      cc::RenderPass* dest_render_pass);
+  void CopyQuadsToPass(
+      const cc::QuadList& source_quad_list,
+      const cc::SharedQuadStateList& source_shared_quad_state_list,
+      const std::unordered_map<cc::ResourceId, cc::ResourceId>&
+          resource_to_child_map,
+      const gfx::Transform& target_transform,
+      const ClipData& clip_rect,
+      cc::RenderPass* dest_pass,
+      const SurfaceId& surface_id);
+  gfx::Rect PrewalkTree(const SurfaceId& surface_id,
+                        bool in_moved_pixel_surface,
+                        int parent_pass,
+                        PrewalkResult* result);
+  void CopyUndrawnSurfaces(PrewalkResult* prewalk);
+  void CopyPasses(const cc::CompositorFrame& frame, cc::Surface* surface);
+  void AddColorConversionPass();
+
+  // Remove Surfaces that were referenced before but aren't currently
+  // referenced from the ResourceProvider.
+  // Also notifies SurfaceAggregatorClient of newly added and removed
+  // child surfaces.
+  void ProcessAddedAndRemovedSurfaces();
+
+  void PropagateCopyRequestPasses();
+
+  int ChildIdForSurface(cc::Surface* surface);
+  gfx::Rect DamageRectForSurface(const cc::Surface* surface,
+                                 const cc::RenderPass& source,
+                                 const gfx::Rect& full_rect) const;
+
+  static void UnrefResources(base::WeakPtr<cc::SurfaceClient> surface_client,
+                             const std::vector<cc::ReturnedResource>& resources,
+                             cc::BlockingTaskRunner* main_thread_task_runner);
+
+  cc::SurfaceManager* manager_;
+  cc::ResourceProvider* provider_;
+
+  // Every Surface has its own RenderPass ID namespace. This structure maps
+  // each source (SurfaceId, RenderPass id) to a unified ID namespace that's
+  // used in the aggregated frame. An entry is removed from the map if it's not
+  // used for one output frame.
+  base::flat_map<std::pair<SurfaceId, cc::RenderPassId>, RenderPassInfo>
+      render_pass_allocator_map_;
+  cc::RenderPassId next_render_pass_id_;
+  const bool aggregate_only_damaged_;
+  bool output_is_secure_;
+
+  // The color space for the root render pass. If this is different from
+  // |blending_color_space_|, then a final render pass to convert between
+  // the two will be added. This space must always be valid.
+  gfx::ColorSpace output_color_space_ = gfx::ColorSpace::CreateSRGB();
+  // The color space in which blending is done, used for all non-root render
+  // passes. This space must always be valid.
+  gfx::ColorSpace blending_color_space_ = gfx::ColorSpace::CreateSRGB();
+  // The id for the final color conversion render pass.
+  cc::RenderPassId color_conversion_render_pass_id_ = 0;
+
+  base::flat_map<SurfaceId, int> surface_id_to_resource_child_id_;
+
+  // The following state is only valid for the duration of one Aggregate call
+  // and is only stored on the class to avoid having to pass through every
+  // function call.
+
+  // This is the set of surfaces referenced in the aggregation so far, used to
+  // detect cycles.
+  base::flat_set<SurfaceId> referenced_surfaces_;
+
+  // For each Surface used in the last aggregation, gives the frame_index at
+  // that time.
+  SurfaceIndexMap previous_contained_surfaces_;
+  SurfaceIndexMap contained_surfaces_;
+
+  // After surface validation, every Surface in this set is valid.
+  base::flat_set<SurfaceId> valid_surfaces_;
+
+  // This is the pass list for the aggregated frame.
+  cc::RenderPassList* dest_pass_list_;
+
+  // This is the set of aggregated pass ids that are affected by filters that
+  // move pixels.
+  base::flat_set<cc::RenderPassId> moved_pixel_passes_;
+
+  // This is the set of aggregated pass ids that are drawn by copy requests, so
+  // should not have their damage rects clipped to the root damage rect.
+  base::flat_set<cc::RenderPassId> copy_request_passes_;
+
+  // This maps each aggregated pass id to the set of (aggregated) pass ids
+  // that its RenderPassDrawQuads depend on
+  base::flat_map<cc::RenderPassId, base::flat_set<cc::RenderPassId>>
+      render_pass_dependencies_;
+
+  // The root damage rect of the currently-aggregating frame.
+  gfx::Rect root_damage_rect_;
+
+  // True if the frame that's currently being aggregated has copy requests.
+  // This is valid during Aggregate after PrewalkTree is called.
+  bool has_copy_requests_;
+
+  // Tracks UMA stats for SurfaceDrawQuads during a call to Aggregate().
+  SurfaceDrawQuadUmaStats uma_stats_;
+
+  base::WeakPtrFactory<SurfaceAggregator> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(SurfaceAggregator);
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_SERVICE_DISPLAY_SURFACE_AGGREGATOR_H_
diff --git a/components/viz/service/display/surface_aggregator_perftest.cc b/components/viz/service/display/surface_aggregator_perftest.cc
new file mode 100644
index 0000000..2979a7a
--- /dev/null
+++ b/components/viz/service/display/surface_aggregator_perftest.cc
@@ -0,0 +1,187 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/memory/ptr_util.h"
+#include "cc/base/lap_timer.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/quads/surface_draw_quad.h"
+#include "cc/quads/texture_draw_quad.h"
+#include "cc/surfaces/frame_sink_manager.h"
+#include "cc/surfaces/surface_manager.h"
+#include "cc/test/compositor_frame_helpers.h"
+#include "cc/test/fake_output_surface_client.h"
+#include "cc/test/fake_resource_provider.h"
+#include "cc/test/test_context_provider.h"
+#include "cc/test/test_shared_bitmap_manager.h"
+#include "components/viz/service/display/surface_aggregator.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "testing/perf/perf_test.h"
+
+namespace viz {
+namespace {
+
+constexpr bool kIsRoot = true;
+constexpr bool kIsChildRoot = false;
+constexpr bool kHandlesFrameSinkIdInvalidation = true;
+constexpr bool kNeedsSyncPoints = true;
+
+const base::UnguessableToken kArbitraryToken = base::UnguessableToken::Create();
+
+class SurfaceAggregatorPerfTest : public testing::Test {
+ public:
+  SurfaceAggregatorPerfTest() {
+    context_provider_ = cc::TestContextProvider::Create();
+    context_provider_->BindToCurrentThread();
+    shared_bitmap_manager_ = base::MakeUnique<cc::TestSharedBitmapManager>();
+
+    resource_provider_ = cc::FakeResourceProvider::Create(
+        context_provider_.get(), shared_bitmap_manager_.get());
+  }
+
+  void RunTest(int num_surfaces,
+               int num_textures,
+               float opacity,
+               bool optimize_damage,
+               bool full_damage,
+               const std::string& name) {
+    std::vector<std::unique_ptr<CompositorFrameSinkSupport>> child_supports(
+        num_surfaces);
+    for (int i = 0; i < num_surfaces; i++) {
+      child_supports[i] = CompositorFrameSinkSupport::Create(
+          nullptr, &manager_, FrameSinkId(1, i + 1), kIsChildRoot,
+          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+    }
+    aggregator_ = base::MakeUnique<SurfaceAggregator>(
+        manager_.surface_manager(), resource_provider_.get(), optimize_damage);
+    for (int i = 0; i < num_surfaces; i++) {
+      LocalSurfaceId local_surface_id(i + 1, kArbitraryToken);
+
+      auto pass = cc::RenderPass::Create();
+      pass->output_rect = gfx::Rect(0, 0, 1, 2);
+
+      cc::CompositorFrame frame = cc::test::MakeEmptyCompositorFrame();
+
+      auto* sqs = pass->CreateAndAppendSharedQuadState();
+      for (int j = 0; j < num_textures; j++) {
+        cc::TransferableResource resource;
+        resource.id = j;
+        resource.is_software = true;
+        frame.resource_list.push_back(resource);
+
+        auto* quad = pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>();
+        const gfx::Rect rect(0, 0, 1, 2);
+        const gfx::Rect opaque_rect;
+        // Half of rects should be visible with partial damage.
+        gfx::Rect visible_rect =
+            j % 2 == 0 ? gfx::Rect(0, 0, 1, 2) : gfx::Rect(0, 1, 1, 1);
+        bool needs_blending = false;
+        bool premultiplied_alpha = false;
+        const gfx::PointF uv_top_left;
+        const gfx::PointF uv_bottom_right;
+        SkColor background_color = SK_ColorGREEN;
+        const float vertex_opacity[4] = {0.f, 0.f, 1.f, 1.f};
+        bool flipped = false;
+        bool nearest_neighbor = false;
+        quad->SetAll(sqs, rect, opaque_rect, visible_rect, needs_blending, j,
+                     gfx::Size(), premultiplied_alpha, uv_top_left,
+                     uv_bottom_right, background_color, vertex_opacity, flipped,
+                     nearest_neighbor, false);
+      }
+      sqs = pass->CreateAndAppendSharedQuadState();
+      sqs->opacity = opacity;
+      if (i >= 1) {
+        auto* surface_quad =
+            pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
+        surface_quad->SetNew(
+            sqs, gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1),
+            SurfaceId(FrameSinkId(1, i), LocalSurfaceId(i, kArbitraryToken)),
+            cc::SurfaceDrawQuadType::PRIMARY, nullptr);
+      }
+
+      frame.render_pass_list.push_back(std::move(pass));
+      child_supports[i]->SubmitCompositorFrame(local_surface_id,
+                                               std::move(frame));
+    }
+
+    auto root_support = CompositorFrameSinkSupport::Create(
+        nullptr, &manager_, FrameSinkId(1, num_surfaces + 1), kIsRoot,
+        kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+    timer_.Reset();
+    do {
+      auto pass = cc::RenderPass::Create();
+      cc::CompositorFrame frame = cc::test::MakeEmptyCompositorFrame();
+
+      auto* sqs = pass->CreateAndAppendSharedQuadState();
+      auto* surface_quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
+      surface_quad->SetNew(
+          sqs, gfx::Rect(0, 0, 100, 100), gfx::Rect(0, 0, 100, 100),
+          SurfaceId(FrameSinkId(1, num_surfaces),
+                    LocalSurfaceId(num_surfaces, kArbitraryToken)),
+          cc::SurfaceDrawQuadType::PRIMARY, nullptr);
+
+      pass->output_rect = gfx::Rect(0, 0, 100, 100);
+
+      if (full_damage)
+        pass->damage_rect = gfx::Rect(0, 0, 100, 100);
+      else
+        pass->damage_rect = gfx::Rect(0, 0, 1, 1);
+
+      frame.render_pass_list.push_back(std::move(pass));
+
+      root_support->SubmitCompositorFrame(
+          LocalSurfaceId(num_surfaces + 1, kArbitraryToken), std::move(frame));
+
+      cc::CompositorFrame aggregated = aggregator_->Aggregate(
+          SurfaceId(FrameSinkId(1, num_surfaces + 1),
+                    LocalSurfaceId(num_surfaces + 1, kArbitraryToken)));
+      timer_.NextLap();
+    } while (!timer_.HasTimeLimitExpired());
+
+    perf_test::PrintResult("aggregator_speed", "", name, timer_.LapsPerSecond(),
+                           "runs/s", true);
+    for (int i = 0; i < num_surfaces; i++)
+      child_supports[i]->EvictCurrentSurface();
+    root_support->EvictCurrentSurface();
+  }
+
+ protected:
+  cc::FrameSinkManager manager_;
+  scoped_refptr<cc::TestContextProvider> context_provider_;
+  std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_;
+  std::unique_ptr<cc::ResourceProvider> resource_provider_;
+  std::unique_ptr<SurfaceAggregator> aggregator_;
+  cc::LapTimer timer_;
+};
+
+TEST_F(SurfaceAggregatorPerfTest, ManySurfacesOpaque) {
+  RunTest(20, 100, 1.f, false, true, "many_surfaces_opaque");
+}
+
+TEST_F(SurfaceAggregatorPerfTest, ManySurfacesTransparent) {
+  RunTest(20, 100, .5f, false, true, "many_surfaces_transparent");
+}
+
+TEST_F(SurfaceAggregatorPerfTest, FewSurfaces) {
+  RunTest(3, 1000, 1.f, false, true, "few_surfaces");
+}
+
+TEST_F(SurfaceAggregatorPerfTest, ManySurfacesOpaqueDamageCalc) {
+  RunTest(20, 100, 1.f, true, true, "many_surfaces_opaque_damage_calc");
+}
+
+TEST_F(SurfaceAggregatorPerfTest, ManySurfacesTransparentDamageCalc) {
+  RunTest(20, 100, .5f, true, true, "many_surfaces_transparent_damage_calc");
+}
+
+TEST_F(SurfaceAggregatorPerfTest, FewSurfacesDamageCalc) {
+  RunTest(3, 1000, 1.f, true, true, "few_surfaces_damage_calc");
+}
+
+TEST_F(SurfaceAggregatorPerfTest, FewSurfacesAggregateDamaged) {
+  RunTest(3, 1000, 1.f, true, false, "few_surfaces_aggregate_damaged");
+}
+
+}  // namespace
+}  // namespace viz
diff --git a/components/viz/service/display/surface_aggregator_pixeltest.cc b/components/viz/service/display/surface_aggregator_pixeltest.cc
new file mode 100644
index 0000000..d762041
--- /dev/null
+++ b/components/viz/service/display/surface_aggregator_pixeltest.cc
@@ -0,0 +1,319 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "build/build_config.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/quads/render_pass.h"
+#include "cc/quads/solid_color_draw_quad.h"
+#include "cc/quads/surface_draw_quad.h"
+#include "cc/surfaces/frame_sink_manager.h"
+#include "cc/surfaces/surface.h"
+#include "cc/surfaces/surface_manager.h"
+#include "cc/test/compositor_frame_helpers.h"
+#include "cc/test/pixel_comparator.h"
+#include "cc/test/pixel_test.h"
+#include "components/viz/common/local_surface_id_allocator.h"
+#include "components/viz/service/display/surface_aggregator.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+#if !defined(OS_ANDROID)
+
+namespace viz {
+namespace {
+
+constexpr FrameSinkId kArbitraryRootFrameSinkId(1, 1);
+constexpr FrameSinkId kArbitraryChildFrameSinkId(2, 2);
+constexpr FrameSinkId kArbitraryLeftFrameSinkId(3, 3);
+constexpr FrameSinkId kArbitraryRightFrameSinkId(4, 4);
+constexpr bool kIsRoot = true;
+constexpr bool kIsChildRoot = false;
+constexpr bool kHandlesFrameSinkIdInvalidation = true;
+constexpr bool kNeedsSyncPoints = true;
+
+class SurfaceAggregatorPixelTest
+    : public cc::RendererPixelTest<cc::GLRenderer> {
+ public:
+  SurfaceAggregatorPixelTest()
+      : support_(
+            CompositorFrameSinkSupport::Create(nullptr,
+                                               &manager_,
+                                               kArbitraryRootFrameSinkId,
+                                               kIsRoot,
+                                               kHandlesFrameSinkIdInvalidation,
+                                               kNeedsSyncPoints)) {}
+  ~SurfaceAggregatorPixelTest() override { support_->EvictCurrentSurface(); }
+
+ protected:
+  cc::FrameSinkManager manager_;
+  LocalSurfaceIdAllocator allocator_;
+  std::unique_ptr<CompositorFrameSinkSupport> support_;
+};
+
+cc::SharedQuadState* CreateAndAppendTestSharedQuadState(
+    cc::RenderPass* render_pass,
+    const gfx::Transform& transform,
+    const gfx::Size& size) {
+  const gfx::Rect layer_rect = gfx::Rect(size);
+  const gfx::Rect visible_layer_rect = gfx::Rect(size);
+  const gfx::Rect clip_rect = gfx::Rect(size);
+  bool is_clipped = false;
+  float opacity = 1.f;
+  const SkBlendMode blend_mode = SkBlendMode::kSrcOver;
+  auto* shared_state = render_pass->CreateAndAppendSharedQuadState();
+  shared_state->SetAll(transform, layer_rect, visible_layer_rect, clip_rect,
+                       is_clipped, opacity, blend_mode, 0);
+  return shared_state;
+}
+
+// Draws a very simple frame with no surface references.
+TEST_F(SurfaceAggregatorPixelTest, DrawSimpleFrame) {
+  gfx::Rect rect(device_viewport_size_);
+  int id = 1;
+  auto pass = cc::RenderPass::Create();
+  pass->SetNew(id, rect, rect, gfx::Transform());
+
+  CreateAndAppendTestSharedQuadState(pass.get(), gfx::Transform(),
+                                     device_viewport_size_);
+
+  auto* color_quad = pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
+  bool force_anti_aliasing_off = false;
+  color_quad->SetNew(pass->shared_quad_state_list.back(), rect, rect,
+                     SK_ColorGREEN, force_anti_aliasing_off);
+
+  auto root_frame = cc::test::MakeCompositorFrame();
+  root_frame.render_pass_list.push_back(std::move(pass));
+
+  LocalSurfaceId root_local_surface_id = allocator_.GenerateId();
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id);
+  support_->SubmitCompositorFrame(root_local_surface_id, std::move(root_frame));
+
+  SurfaceAggregator aggregator(manager_.surface_manager(),
+                               resource_provider_.get(), true);
+  cc::CompositorFrame aggregated_frame = aggregator.Aggregate(root_surface_id);
+
+  bool discard_alpha = false;
+  cc::ExactPixelComparator pixel_comparator(discard_alpha);
+  cc::RenderPassList* pass_list = &aggregated_frame.render_pass_list;
+  EXPECT_TRUE(RunPixelTest(pass_list,
+                           base::FilePath(FILE_PATH_LITERAL("green.png")),
+                           pixel_comparator));
+}
+
+// Draws a frame with simple surface embedding.
+TEST_F(SurfaceAggregatorPixelTest, DrawSimpleAggregatedFrame) {
+  gfx::Size child_size(200, 100);
+  std::unique_ptr<CompositorFrameSinkSupport> child_support =
+      CompositorFrameSinkSupport::Create(
+          nullptr, &manager_, kArbitraryChildFrameSinkId, kIsChildRoot,
+          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+
+  LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
+  SurfaceId child_surface_id(child_support->frame_sink_id(),
+                             child_local_surface_id);
+  LocalSurfaceId root_local_surface_id = allocator_.GenerateId();
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id);
+
+  {
+    gfx::Rect rect(device_viewport_size_);
+    int id = 1;
+    auto pass = cc::RenderPass::Create();
+    pass->SetNew(id, rect, rect, gfx::Transform());
+
+    CreateAndAppendTestSharedQuadState(pass.get(), gfx::Transform(),
+                                       device_viewport_size_);
+
+    auto* surface_quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
+    surface_quad->SetNew(pass->shared_quad_state_list.back(),
+                         gfx::Rect(child_size), gfx::Rect(child_size),
+                         child_surface_id, cc::SurfaceDrawQuadType::PRIMARY,
+                         nullptr);
+
+    auto* color_quad = pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
+    bool force_anti_aliasing_off = false;
+    color_quad->SetNew(pass->shared_quad_state_list.back(), rect, rect,
+                       SK_ColorYELLOW, force_anti_aliasing_off);
+
+    auto root_frame = cc::test::MakeCompositorFrame();
+    root_frame.render_pass_list.push_back(std::move(pass));
+
+    support_->SubmitCompositorFrame(root_local_surface_id,
+                                    std::move(root_frame));
+  }
+
+  {
+    gfx::Rect rect(child_size);
+    int id = 1;
+    auto pass = cc::RenderPass::Create();
+    pass->SetNew(id, rect, rect, gfx::Transform());
+
+    CreateAndAppendTestSharedQuadState(pass.get(), gfx::Transform(),
+                                       child_size);
+
+    auto* color_quad = pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
+    bool force_anti_aliasing_off = false;
+    color_quad->SetNew(pass->shared_quad_state_list.back(), rect, rect,
+                       SK_ColorBLUE, force_anti_aliasing_off);
+
+    auto child_frame = cc::test::MakeCompositorFrame();
+    child_frame.render_pass_list.push_back(std::move(pass));
+
+    child_support->SubmitCompositorFrame(child_local_surface_id,
+                                         std::move(child_frame));
+  }
+
+  SurfaceAggregator aggregator(manager_.surface_manager(),
+                               resource_provider_.get(), true);
+  cc::CompositorFrame aggregated_frame = aggregator.Aggregate(root_surface_id);
+
+  bool discard_alpha = false;
+  cc::ExactPixelComparator pixel_comparator(discard_alpha);
+  cc::RenderPassList* pass_list = &aggregated_frame.render_pass_list;
+  EXPECT_TRUE(RunPixelTest(pass_list,
+                           base::FilePath(FILE_PATH_LITERAL("blue_yellow.png")),
+                           pixel_comparator));
+
+  child_support->EvictCurrentSurface();
+}
+
+// Tests a surface quad that has a non-identity transform into its pass.
+TEST_F(SurfaceAggregatorPixelTest, DrawAggregatedFrameWithSurfaceTransforms) {
+  gfx::Size child_size(100, 200);
+  gfx::Size quad_size(100, 100);
+  // Structure:
+  // root (200x200) -> left_child (100x200 @ 0x0,
+  //                   right_child (100x200 @ 0x100)
+  //   left_child -> top_green_quad (100x100 @ 0x0),
+  //                 bottom_blue_quad (100x100 @ 0x100)
+  //   right_child -> top_blue_quad (100x100 @ 0x0),
+  //                  bottom_green_quad (100x100 @ 0x100)
+  std::unique_ptr<CompositorFrameSinkSupport> left_support =
+      CompositorFrameSinkSupport::Create(
+          nullptr, &manager_, kArbitraryLeftFrameSinkId, kIsChildRoot,
+          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  std::unique_ptr<CompositorFrameSinkSupport> right_support =
+      CompositorFrameSinkSupport::Create(
+          nullptr, &manager_, kArbitraryRightFrameSinkId, kIsChildRoot,
+          kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId left_child_local_id = allocator_.GenerateId();
+  SurfaceId left_child_id(left_support->frame_sink_id(), left_child_local_id);
+  LocalSurfaceId right_child_local_id = allocator_.GenerateId();
+  SurfaceId right_child_id(right_support->frame_sink_id(),
+                           right_child_local_id);
+  LocalSurfaceId root_local_surface_id = allocator_.GenerateId();
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id);
+
+  {
+    gfx::Rect rect(device_viewport_size_);
+    int id = 1;
+    auto pass = cc::RenderPass::Create();
+    pass->SetNew(id, rect, rect, gfx::Transform());
+
+    gfx::Transform surface_transform;
+    CreateAndAppendTestSharedQuadState(pass.get(), surface_transform,
+                                       device_viewport_size_);
+
+    auto* left_surface_quad =
+        pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
+    left_surface_quad->SetNew(pass->shared_quad_state_list.back(),
+                              gfx::Rect(child_size), gfx::Rect(child_size),
+                              left_child_id, cc::SurfaceDrawQuadType::PRIMARY,
+                              nullptr);
+
+    surface_transform.Translate(100, 0);
+    CreateAndAppendTestSharedQuadState(pass.get(), surface_transform,
+                                       device_viewport_size_);
+
+    auto* right_surface_quad =
+        pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
+    right_surface_quad->SetNew(pass->shared_quad_state_list.back(),
+                               gfx::Rect(child_size), gfx::Rect(child_size),
+                               right_child_id, cc::SurfaceDrawQuadType::PRIMARY,
+                               nullptr);
+
+    auto root_frame = cc::test::MakeCompositorFrame();
+    root_frame.render_pass_list.push_back(std::move(pass));
+
+    support_->SubmitCompositorFrame(root_local_surface_id,
+                                    std::move(root_frame));
+  }
+
+  {
+    gfx::Rect rect(child_size);
+    int id = 1;
+    auto pass = cc::RenderPass::Create();
+    pass->SetNew(id, rect, rect, gfx::Transform());
+
+    CreateAndAppendTestSharedQuadState(pass.get(), gfx::Transform(),
+                                       child_size);
+
+    auto* top_color_quad =
+        pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
+    bool force_anti_aliasing_off = false;
+    top_color_quad->SetNew(pass->shared_quad_state_list.back(),
+                           gfx::Rect(quad_size), gfx::Rect(quad_size),
+                           SK_ColorGREEN, force_anti_aliasing_off);
+
+    auto* bottom_color_quad =
+        pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
+    bottom_color_quad->SetNew(
+        pass->shared_quad_state_list.back(), gfx::Rect(0, 100, 100, 100),
+        gfx::Rect(0, 100, 100, 100), SK_ColorBLUE, force_anti_aliasing_off);
+
+    auto child_frame = cc::test::MakeCompositorFrame();
+    child_frame.render_pass_list.push_back(std::move(pass));
+
+    left_support->SubmitCompositorFrame(left_child_local_id,
+                                        std::move(child_frame));
+  }
+
+  {
+    gfx::Rect rect(child_size);
+    int id = 1;
+    auto pass = cc::RenderPass::Create();
+    pass->SetNew(id, rect, rect, gfx::Transform());
+
+    CreateAndAppendTestSharedQuadState(pass.get(), gfx::Transform(),
+                                       child_size);
+
+    auto* top_color_quad =
+        pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
+    bool force_anti_aliasing_off = false;
+    top_color_quad->SetNew(pass->shared_quad_state_list.back(),
+                           gfx::Rect(quad_size), gfx::Rect(quad_size),
+                           SK_ColorBLUE, force_anti_aliasing_off);
+
+    auto* bottom_color_quad =
+        pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
+    bottom_color_quad->SetNew(
+        pass->shared_quad_state_list.back(), gfx::Rect(0, 100, 100, 100),
+        gfx::Rect(0, 100, 100, 100), SK_ColorGREEN, force_anti_aliasing_off);
+
+    auto child_frame = cc::test::MakeCompositorFrame();
+    child_frame.render_pass_list.push_back(std::move(pass));
+
+    right_support->SubmitCompositorFrame(right_child_local_id,
+                                         std::move(child_frame));
+  }
+
+  SurfaceAggregator aggregator(manager_.surface_manager(),
+                               resource_provider_.get(), true);
+  cc::CompositorFrame aggregated_frame = aggregator.Aggregate(root_surface_id);
+
+  bool discard_alpha = false;
+  cc::ExactPixelComparator pixel_comparator(discard_alpha);
+  cc::RenderPassList* pass_list = &aggregated_frame.render_pass_list;
+  EXPECT_TRUE(RunPixelTest(
+      pass_list,
+      base::FilePath(FILE_PATH_LITERAL("four_blue_green_checkers.png")),
+      pixel_comparator));
+
+  left_support->EvictCurrentSurface();
+  right_support->EvictCurrentSurface();
+}
+
+}  // namespace
+}  // namespace viz
+
+#endif  // !defined(OS_ANDROID)
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc
new file mode 100644
index 0000000..ec1f83ce
--- /dev/null
+++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -0,0 +1,2461 @@
+
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/display/surface_aggregator.h"
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <utility>
+
+#include "base/macros.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/stringprintf.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/quads/render_pass.h"
+#include "cc/quads/render_pass_draw_quad.h"
+#include "cc/quads/solid_color_draw_quad.h"
+#include "cc/quads/surface_draw_quad.h"
+#include "cc/quads/texture_draw_quad.h"
+#include "cc/surfaces/frame_sink_manager.h"
+#include "cc/surfaces/surface.h"
+#include "cc/surfaces/surface_manager.h"
+#include "cc/test/compositor_frame_helpers.h"
+#include "cc/test/fake_compositor_frame_sink_support_client.h"
+#include "cc/test/fake_resource_provider.h"
+#include "cc/test/fake_surface_observer.h"
+#include "cc/test/render_pass_test_utils.h"
+#include "cc/test/test_shared_bitmap_manager.h"
+#include "components/viz/common/local_surface_id_allocator.h"
+#include "components/viz/common/resources/shared_bitmap_manager.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkColor.h"
+
+namespace viz {
+namespace {
+
+constexpr FrameSinkId kArbitraryRootFrameSinkId(1, 1);
+constexpr FrameSinkId kArbitraryFrameSinkId1(2, 2);
+constexpr FrameSinkId kArbitraryFrameSinkId2(3, 3);
+constexpr FrameSinkId kArbitraryMiddleFrameSinkId(4, 4);
+constexpr FrameSinkId kArbitraryReservedFrameSinkId(5, 5);
+constexpr FrameSinkId kArbitraryFrameSinkId3(6, 6);
+const base::UnguessableToken kArbitraryToken = base::UnguessableToken::Create();
+constexpr bool kRootIsRoot = true;
+constexpr bool kChildIsRoot = false;
+constexpr bool kHandlesFrameSinkIdInvalidation = true;
+constexpr bool kNeedsSyncPoints = false;
+
+SurfaceId InvalidSurfaceId() {
+  static SurfaceId invalid(FrameSinkId(),
+                           LocalSurfaceId(0xdeadbeef, kArbitraryToken));
+  return invalid;
+}
+
+gfx::Size SurfaceSize() {
+  static gfx::Size size(100, 100);
+  return size;
+}
+
+class SurfaceAggregatorTest : public testing::Test {
+ public:
+  explicit SurfaceAggregatorTest(bool use_damage_rect)
+      : observer_(false),
+        support_(
+            CompositorFrameSinkSupport::Create(&fake_client_,
+                                               &manager_,
+                                               kArbitraryRootFrameSinkId,
+                                               kRootIsRoot,
+                                               kHandlesFrameSinkIdInvalidation,
+                                               kNeedsSyncPoints)),
+        aggregator_(manager_.surface_manager(), NULL, use_damage_rect) {
+    manager_.surface_manager()->AddObserver(&observer_);
+  }
+
+  SurfaceAggregatorTest() : SurfaceAggregatorTest(false) {}
+
+  void TearDown() override {
+    observer_.Reset();
+    support_->EvictCurrentSurface();
+    testing::Test::TearDown();
+  }
+
+  struct Quad {
+    static Quad SolidColorQuad(SkColor color) {
+      Quad quad;
+      quad.material = cc::DrawQuad::SOLID_COLOR;
+      quad.color = color;
+      return quad;
+    }
+
+    static Quad SurfaceQuad(const SurfaceId& primary_surface_id,
+                            const SurfaceId& fallback_surface_id,
+                            float opacity) {
+      Quad quad;
+      quad.material = cc::DrawQuad::SURFACE_CONTENT;
+      quad.opacity = opacity;
+      quad.primary_surface_id = primary_surface_id;
+      quad.fallback_surface_id = fallback_surface_id;
+      return quad;
+    }
+
+    static Quad RenderPassQuad(int id) {
+      Quad quad;
+      quad.material = cc::DrawQuad::RENDER_PASS;
+      quad.render_pass_id = id;
+      return quad;
+    }
+
+    cc::DrawQuad::Material material;
+    // Set when material==DrawQuad::SURFACE_CONTENT.
+    SurfaceId primary_surface_id;
+    SurfaceId fallback_surface_id;
+    float opacity;
+    // Set when material==DrawQuad::SOLID_COLOR.
+    SkColor color;
+    // Set when material==DrawQuad::RENDER_PASS.
+    cc::RenderPassId render_pass_id;
+
+   private:
+    Quad()
+        : material(cc::DrawQuad::INVALID), opacity(1.f), color(SK_ColorWHITE) {}
+  };
+
+  struct Pass {
+    Pass(Quad* quads, size_t quad_count, int id)
+        : quads(quads), quad_count(quad_count), id(id) {}
+    Pass(Quad* quads, size_t quad_count)
+        : quads(quads), quad_count(quad_count) {}
+
+    Quad* quads;
+    size_t quad_count;
+    int id = 1;
+  };
+
+  static void AddQuadInPass(cc::RenderPass* pass, Quad desc) {
+    switch (desc.material) {
+      case cc::DrawQuad::SOLID_COLOR:
+        AddQuad(pass, gfx::Rect(0, 0, 5, 5), desc.color);
+        break;
+      case cc::DrawQuad::SURFACE_CONTENT:
+        AddSurfaceQuad(pass, gfx::Size(5, 5), desc.opacity,
+                       desc.primary_surface_id, desc.fallback_surface_id);
+        break;
+      case cc::DrawQuad::RENDER_PASS:
+        AddRenderPassQuad(pass, desc.render_pass_id);
+        break;
+      default:
+        NOTREACHED();
+    }
+  }
+
+  static void AddPasses(cc::RenderPassList* pass_list,
+                        const gfx::Rect& output_rect,
+                        Pass* passes,
+                        size_t pass_count) {
+    gfx::Transform root_transform;
+    for (size_t i = 0; i < pass_count; ++i) {
+      Pass pass = passes[i];
+      cc::RenderPass* test_pass =
+          AddRenderPass(pass_list, pass.id, output_rect, root_transform,
+                        cc::FilterOperations());
+      for (size_t j = 0; j < pass.quad_count; ++j) {
+        AddQuadInPass(test_pass, pass.quads[j]);
+      }
+    }
+  }
+
+  static void TestQuadMatchesExpectations(Quad expected_quad,
+                                          const cc::DrawQuad* quad) {
+    switch (expected_quad.material) {
+      case cc::DrawQuad::SOLID_COLOR: {
+        ASSERT_EQ(cc::DrawQuad::SOLID_COLOR, quad->material);
+
+        const auto* solid_color_quad =
+            cc::SolidColorDrawQuad::MaterialCast(quad);
+
+        EXPECT_EQ(expected_quad.color, solid_color_quad->color);
+        break;
+      }
+      case cc::DrawQuad::RENDER_PASS: {
+        ASSERT_EQ(cc::DrawQuad::RENDER_PASS, quad->material);
+
+        const auto* render_pass_quad =
+            cc::RenderPassDrawQuad::MaterialCast(quad);
+
+        EXPECT_EQ(expected_quad.render_pass_id,
+                  render_pass_quad->render_pass_id);
+        break;
+      }
+      default:
+        NOTREACHED();
+        break;
+    }
+  }
+
+  static void TestPassMatchesExpectations(Pass expected_pass,
+                                          const cc::RenderPass* pass) {
+    ASSERT_EQ(expected_pass.quad_count, pass->quad_list.size());
+    for (auto iter = pass->quad_list.cbegin(); iter != pass->quad_list.cend();
+         ++iter) {
+      SCOPED_TRACE(base::StringPrintf("Quad number %" PRIuS, iter.index()));
+      TestQuadMatchesExpectations(expected_pass.quads[iter.index()], *iter);
+    }
+  }
+
+  static void TestPassesMatchExpectations(Pass* expected_passes,
+                                          size_t expected_pass_count,
+                                          const cc::RenderPassList* passes) {
+    ASSERT_EQ(expected_pass_count, passes->size());
+
+    for (size_t i = 0; i < passes->size(); ++i) {
+      SCOPED_TRACE(base::StringPrintf("Pass number %" PRIuS, i));
+      cc::RenderPass* pass = (*passes)[i].get();
+      TestPassMatchesExpectations(expected_passes[i], pass);
+    }
+  }
+
+ private:
+  static void AddSurfaceQuad(cc::RenderPass* pass,
+                             const gfx::Size& surface_size,
+                             float opacity,
+                             const SurfaceId& primary_surface_id,
+                             const SurfaceId& fallback_surface_id) {
+    gfx::Transform layer_to_target_transform;
+    gfx::Size layer_bounds = surface_size;
+    gfx::Rect visible_layer_rect = gfx::Rect(surface_size);
+    gfx::Rect clip_rect = gfx::Rect(surface_size);
+    bool is_clipped = false;
+    SkBlendMode blend_mode = SkBlendMode::kSrcOver;
+
+    auto* shared_quad_state = pass->CreateAndAppendSharedQuadState();
+    shared_quad_state->SetAll(layer_to_target_transform,
+                              gfx::Rect(layer_bounds), visible_layer_rect,
+                              clip_rect, is_clipped, opacity, blend_mode, 0);
+
+    cc::SurfaceDrawQuad* surface_quad =
+        pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
+    cc::SurfaceDrawQuad* fallback_surface_quad = nullptr;
+    if (fallback_surface_id.is_valid())
+      fallback_surface_quad =
+          pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
+
+    gfx::Rect quad_rect = gfx::Rect(surface_size);
+    surface_quad->SetNew(pass->shared_quad_state_list.back(), quad_rect,
+                         quad_rect, primary_surface_id,
+                         cc::SurfaceDrawQuadType::PRIMARY,
+                         fallback_surface_quad);
+
+    if (fallback_surface_quad) {
+      fallback_surface_quad->SetNew(pass->shared_quad_state_list.back(),
+                                    quad_rect, quad_rect, fallback_surface_id,
+                                    cc::SurfaceDrawQuadType::FALLBACK, nullptr);
+    }
+  }
+
+  static void AddRenderPassQuad(cc::RenderPass* pass,
+                                cc::RenderPassId render_pass_id) {
+    gfx::Rect output_rect = gfx::Rect(0, 0, 5, 5);
+    auto* shared_state = pass->CreateAndAppendSharedQuadState();
+    shared_state->SetAll(gfx::Transform(), output_rect, output_rect,
+                         output_rect, false, 1, SkBlendMode::kSrcOver, 0);
+    auto* quad = pass->CreateAndAppendDrawQuad<cc::RenderPassDrawQuad>();
+    quad->SetNew(shared_state, output_rect, output_rect, render_pass_id, 0,
+                 gfx::RectF(), gfx::Size(), gfx::Vector2dF(), gfx::PointF(),
+                 gfx::RectF());
+  }
+
+ protected:
+  cc::FrameSinkManager manager_;
+  cc::FakeSurfaceObserver observer_;
+  cc::FakeCompositorFrameSinkSupportClient fake_client_;
+  std::unique_ptr<CompositorFrameSinkSupport> support_;
+  SurfaceAggregator aggregator_;
+};
+
+class SurfaceAggregatorValidSurfaceTest : public SurfaceAggregatorTest {
+ public:
+  explicit SurfaceAggregatorValidSurfaceTest(bool use_damage_rect)
+      : SurfaceAggregatorTest(use_damage_rect),
+        child_support_(
+            CompositorFrameSinkSupport::Create(nullptr,
+                                               &manager_,
+                                               kArbitraryReservedFrameSinkId,
+                                               kChildIsRoot,
+                                               kHandlesFrameSinkIdInvalidation,
+                                               kNeedsSyncPoints)) {}
+  SurfaceAggregatorValidSurfaceTest()
+      : SurfaceAggregatorValidSurfaceTest(false) {}
+
+  void SetUp() override {
+    SurfaceAggregatorTest::SetUp();
+    root_local_surface_id_ = allocator_.GenerateId();
+    root_surface_ = manager_.surface_manager()->GetSurfaceForId(
+        SurfaceId(support_->frame_sink_id(), root_local_surface_id_));
+  }
+
+  void TearDown() override {
+    child_support_->EvictCurrentSurface();
+    SurfaceAggregatorTest::TearDown();
+  }
+
+  void AggregateAndVerify(Pass* expected_passes,
+                          size_t expected_pass_count,
+                          SurfaceId* surface_ids,
+                          size_t expected_surface_count) {
+    cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(
+        SurfaceId(support_->frame_sink_id(), root_local_surface_id_));
+
+    TestPassesMatchExpectations(expected_passes, expected_pass_count,
+                                &aggregated_frame.render_pass_list);
+
+    // Ensure no duplicate pass ids output.
+    std::set<cc::RenderPassId> used_passes;
+    for (const auto& pass : aggregated_frame.render_pass_list) {
+      EXPECT_TRUE(used_passes.insert(pass->id).second);
+    }
+
+    EXPECT_EQ(expected_surface_count,
+              aggregator_.previous_contained_surfaces().size());
+    for (size_t i = 0; i < expected_surface_count; i++) {
+      EXPECT_TRUE(
+          aggregator_.previous_contained_surfaces().find(surface_ids[i]) !=
+          aggregator_.previous_contained_surfaces().end());
+    }
+  }
+
+  void SubmitPassListAsFrame(CompositorFrameSinkSupport* support,
+                             const LocalSurfaceId& local_surface_id,
+                             cc::RenderPassList* pass_list) {
+    cc::CompositorFrame frame = cc::test::MakeEmptyCompositorFrame();
+    pass_list->swap(frame.render_pass_list);
+
+    support->SubmitCompositorFrame(local_surface_id, std::move(frame));
+  }
+
+  void SubmitCompositorFrame(CompositorFrameSinkSupport* support,
+                             Pass* passes,
+                             size_t pass_count,
+                             const LocalSurfaceId& local_surface_id) {
+    cc::RenderPassList pass_list;
+    AddPasses(&pass_list, gfx::Rect(SurfaceSize()), passes, pass_count);
+    SubmitPassListAsFrame(support, local_surface_id, &pass_list);
+  }
+
+  void QueuePassAsFrame(std::unique_ptr<cc::RenderPass> pass,
+                        const LocalSurfaceId& local_surface_id,
+                        CompositorFrameSinkSupport* support) {
+    cc::CompositorFrame child_frame = cc::test::MakeEmptyCompositorFrame();
+    child_frame.render_pass_list.push_back(std::move(pass));
+
+    support->SubmitCompositorFrame(local_surface_id, std::move(child_frame));
+  }
+
+ protected:
+  LocalSurfaceId root_local_surface_id_;
+  cc::Surface* root_surface_;
+  LocalSurfaceIdAllocator allocator_;
+  std::unique_ptr<CompositorFrameSinkSupport> child_support_;
+  LocalSurfaceIdAllocator child_allocator_;
+};
+
+// Tests that a very simple frame containing only two solid color quads makes it
+// through the aggregator correctly.
+TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleFrame) {
+  Quad quads[] = {Quad::SolidColorQuad(SK_ColorRED),
+                  Quad::SolidColorQuad(SK_ColorBLUE)};
+  Pass passes[] = {Pass(quads, arraysize(quads))};
+
+  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
+                        root_local_surface_id_);
+
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  SurfaceId ids[] = {root_surface_id};
+
+  AggregateAndVerify(passes, arraysize(passes), ids, arraysize(ids));
+
+  // Check that WillDrawSurface was called.
+  EXPECT_EQ(gfx::Rect(SurfaceSize()), fake_client_.last_damage_rect());
+  EXPECT_EQ(root_local_surface_id_, fake_client_.last_local_surface_id());
+
+  // Check that SurfaceObserver::OnSurfaceWillDraw was called.
+  EXPECT_TRUE(observer_.SurfaceWillDrawCalled(root_surface_id));
+}
+
+TEST_F(SurfaceAggregatorValidSurfaceTest, OpacityCopied) {
+  auto embedded_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryFrameSinkId1, kRootIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId embedded_local_surface_id = allocator_.GenerateId();
+  SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
+                                embedded_local_surface_id);
+
+  Quad embedded_quads[] = {Quad::SolidColorQuad(SK_ColorGREEN),
+                           Quad::SolidColorQuad(SK_ColorBLUE)};
+  Pass embedded_passes[] = {Pass(embedded_quads, arraysize(embedded_quads))};
+
+  SubmitCompositorFrame(embedded_support.get(), embedded_passes,
+                        arraysize(embedded_passes), embedded_local_surface_id);
+
+  Quad quads[] = {
+      Quad::SurfaceQuad(embedded_surface_id, InvalidSurfaceId(), .5f)};
+  Pass passes[] = {Pass(quads, arraysize(quads))};
+
+  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
+                        root_local_surface_id_);
+
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+  auto& render_pass_list = aggregated_frame.render_pass_list;
+  ASSERT_EQ(2u, render_pass_list.size());
+  auto& shared_quad_state_list = render_pass_list[0]->shared_quad_state_list;
+  ASSERT_EQ(2u, shared_quad_state_list.size());
+  EXPECT_EQ(1.f, shared_quad_state_list.ElementAt(0)->opacity);
+  EXPECT_EQ(1.f, shared_quad_state_list.ElementAt(1)->opacity);
+
+  auto& shared_quad_state_list2 = render_pass_list[1]->shared_quad_state_list;
+  ASSERT_EQ(1u, shared_quad_state_list2.size());
+  EXPECT_EQ(.5f, shared_quad_state_list2.ElementAt(0)->opacity);
+
+  embedded_support->EvictCurrentSurface();
+}
+
+TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSimpleFrame) {
+  Quad quads[][2] = {{Quad::SolidColorQuad(SK_ColorWHITE),
+                      Quad::SolidColorQuad(SK_ColorLTGRAY)},
+                     {Quad::SolidColorQuad(SK_ColorGRAY),
+                      Quad::SolidColorQuad(SK_ColorDKGRAY)}};
+  Pass passes[] = {Pass(quads[0], arraysize(quads[0]), 1),
+                   Pass(quads[1], arraysize(quads[1]), 2)};
+
+  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
+                        root_local_surface_id_);
+
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  SurfaceId ids[] = {root_surface_id};
+
+  AggregateAndVerify(passes, arraysize(passes), ids, arraysize(ids));
+}
+
+// Ensure that the render pass ID map properly keeps and deletes entries.
+TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassDeallocation) {
+  Quad quads[][2] = {{Quad::SolidColorQuad(SK_ColorWHITE),
+                      Quad::SolidColorQuad(SK_ColorLTGRAY)},
+                     {Quad::SolidColorQuad(SK_ColorGRAY),
+                      Quad::SolidColorQuad(SK_ColorDKGRAY)}};
+  Pass passes[] = {Pass(quads[0], arraysize(quads[0]), 2),
+                   Pass(quads[1], arraysize(quads[1]), 1)};
+
+  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
+                        root_local_surface_id_);
+
+  SurfaceId surface_id(support_->frame_sink_id(), root_local_surface_id_);
+
+  cc::CompositorFrame aggregated_frame;
+  aggregated_frame = aggregator_.Aggregate(surface_id);
+  auto id0 = aggregated_frame.render_pass_list[0]->id;
+  auto id1 = aggregated_frame.render_pass_list[1]->id;
+  EXPECT_NE(id1, id0);
+
+  // Aggregated cc::RenderPass ids should remain the same between frames.
+  aggregated_frame = aggregator_.Aggregate(surface_id);
+  EXPECT_EQ(id0, aggregated_frame.render_pass_list[0]->id);
+  EXPECT_EQ(id1, aggregated_frame.render_pass_list[1]->id);
+
+  Pass passes2[] = {Pass(quads[0], arraysize(quads[0]), 3),
+                    Pass(quads[1], arraysize(quads[1]), 1)};
+
+  SubmitCompositorFrame(support_.get(), passes2, arraysize(passes2),
+                        root_local_surface_id_);
+
+  // The cc::RenderPass that still exists should keep the same ID.
+  aggregated_frame = aggregator_.Aggregate(surface_id);
+  auto id2 = aggregated_frame.render_pass_list[0]->id;
+  EXPECT_NE(id2, id1);
+  EXPECT_NE(id2, id0);
+  EXPECT_EQ(id1, aggregated_frame.render_pass_list[1]->id);
+
+  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
+                        root_local_surface_id_);
+
+  // |id1| didn't exist in the previous frame, so it should be
+  // mapped to a new ID.
+  aggregated_frame = aggregator_.Aggregate(surface_id);
+  auto id3 = aggregated_frame.render_pass_list[0]->id;
+  EXPECT_NE(id3, id2);
+  EXPECT_NE(id3, id1);
+  EXPECT_NE(id3, id0);
+  EXPECT_EQ(id1, aggregated_frame.render_pass_list[1]->id);
+}
+
+// This tests very simple embedding. root_surface has a frame containing a few
+// solid color quads and a surface quad referencing embedded_surface.
+// embedded_surface has a frame containing only a solid color quad. The solid
+// color quad should be aggregated into the final frame.
+TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleSurfaceReference) {
+  auto embedded_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryFrameSinkId1, kRootIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId embedded_local_surface_id = allocator_.GenerateId();
+  SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
+                                embedded_local_surface_id);
+
+  Quad embedded_quads[] = {Quad::SolidColorQuad(SK_ColorGREEN)};
+  Pass embedded_passes[] = {Pass(embedded_quads, arraysize(embedded_quads))};
+
+  SubmitCompositorFrame(embedded_support.get(), embedded_passes,
+                        arraysize(embedded_passes), embedded_local_surface_id);
+
+  Quad root_quads[] = {
+      Quad::SolidColorQuad(SK_ColorWHITE),
+      Quad::SurfaceQuad(embedded_surface_id, InvalidSurfaceId(), 1.f),
+      Quad::SolidColorQuad(SK_ColorBLACK)};
+  Pass root_passes[] = {Pass(root_quads, arraysize(root_quads))};
+
+  SubmitCompositorFrame(support_.get(), root_passes, arraysize(root_passes),
+                        root_local_surface_id_);
+
+  Quad expected_quads[] = {Quad::SolidColorQuad(SK_ColorWHITE),
+                           Quad::SolidColorQuad(SK_ColorGREEN),
+                           Quad::SolidColorQuad(SK_ColorBLACK)};
+  Pass expected_passes[] = {Pass(expected_quads, arraysize(expected_quads))};
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  SurfaceId ids[] = {root_surface_id, embedded_surface_id};
+  AggregateAndVerify(expected_passes, arraysize(expected_passes), ids,
+                     arraysize(ids));
+
+  embedded_support->EvictCurrentSurface();
+}
+
+// This test verifies that in the absence of a primary Surface,
+// SurfaceAggregator will embed a fallback Surface, if available. If the primary
+// Surface is available, though, the fallback will not be used.
+TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReference) {
+  auto primary_child_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId primary_child_local_surface_id = allocator_.GenerateId();
+  SurfaceId primary_child_surface_id(primary_child_support->frame_sink_id(),
+                                     primary_child_local_surface_id);
+
+  auto fallback_child_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryFrameSinkId2, kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId fallback_child_local_surface_id = allocator_.GenerateId();
+  SurfaceId fallback_child_surface_id(fallback_child_support->frame_sink_id(),
+                                      fallback_child_local_surface_id);
+
+  Quad fallback_child_quads[] = {Quad::SolidColorQuad(SK_ColorRED)};
+  Pass fallback_child_passes[] = {
+      Pass(fallback_child_quads, arraysize(fallback_child_quads))};
+
+  // Submit a cc::CompositorFrame to the fallback Surface containing a red
+  // SolidColorDrawQuad.
+  SubmitCompositorFrame(fallback_child_support.get(), fallback_child_passes,
+                        arraysize(fallback_child_passes),
+                        fallback_child_local_surface_id);
+
+  // Try to embed |primary_child_surface_id| and if unavailabe, embed
+  // |fallback_child_surface_id|.
+  Quad root_quads[] = {Quad::SurfaceQuad(primary_child_surface_id,
+                                         fallback_child_surface_id, 1.f)};
+  Pass root_passes[] = {Pass(root_quads, arraysize(root_quads))};
+
+  SubmitCompositorFrame(support_.get(), root_passes, arraysize(root_passes),
+                        root_local_surface_id_);
+
+  // There is no cc::CompositorFrame submitted to |primary_child_surface_id| and
+  // so |fallback_child_surface_id| will be embedded and we should see a red
+  // SolidColorDrawQuad.
+  Quad expected_quads1[] = {Quad::SolidColorQuad(SK_ColorRED)};
+  Pass expected_passes1[] = {Pass(expected_quads1, arraysize(expected_quads1))};
+
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  SurfaceId ids[] = {root_surface_id, primary_child_surface_id,
+                     fallback_child_surface_id};
+  AggregateAndVerify(expected_passes1, arraysize(expected_passes1), ids,
+                     arraysize(ids));
+
+  // Check that SurfaceObserver::OnSurfaceWillDraw was called only
+  // for the fallback surface.
+  EXPECT_FALSE(observer_.SurfaceWillDrawCalled(primary_child_surface_id));
+  EXPECT_TRUE(observer_.SurfaceWillDrawCalled(fallback_child_surface_id));
+
+  observer_.Reset();
+
+  Quad primary_child_quads[] = {Quad::SolidColorQuad(SK_ColorGREEN)};
+  Pass primary_child_passes[] = {
+      Pass(primary_child_quads, arraysize(primary_child_quads))};
+
+  // Submit a cc::CompositorFrame to the primary Surface containing a green
+  // SolidColorDrawQuad.
+  SubmitCompositorFrame(primary_child_support.get(), primary_child_passes,
+                        arraysize(primary_child_passes),
+                        primary_child_local_surface_id);
+
+  // Now that the primary Surface has a cc::CompositorFrame, we expect
+  // SurfaceAggregator to embed the primary Surface, and drop the fallback
+  // Surface.
+  Quad expected_quads2[] = {Quad::SolidColorQuad(SK_ColorGREEN)};
+  Pass expected_passes2[] = {Pass(expected_quads2, arraysize(expected_quads2))};
+  AggregateAndVerify(expected_passes2, arraysize(expected_passes2), ids,
+                     arraysize(ids));
+
+  // Check that SurfaceObserver::OnSurfaceWillDraw was called only
+  // for the primary surface.
+  EXPECT_TRUE(observer_.SurfaceWillDrawCalled(primary_child_surface_id));
+  EXPECT_FALSE(observer_.SurfaceWillDrawCalled(fallback_child_surface_id));
+
+  primary_child_support->EvictCurrentSurface();
+  fallback_child_support->EvictCurrentSurface();
+}
+
+// This test verifies that in the presence of both primary Surface and fallback
+// Surface, the fallback will not be used.
+TEST_F(SurfaceAggregatorValidSurfaceTest, FallbackSurfaceReferenceWithPrimary) {
+  auto primary_child_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId primary_child_local_surface_id = allocator_.GenerateId();
+  SurfaceId primary_child_surface_id(primary_child_support->frame_sink_id(),
+                                     primary_child_local_surface_id);
+  Quad primary_child_quads[] = {Quad::SolidColorQuad(SK_ColorGREEN)};
+  Pass primary_child_passes[] = {
+      Pass(primary_child_quads, arraysize(primary_child_quads))};
+
+  // Submit a cc::CompositorFrame to the primary Surface containing a green
+  // SolidColorDrawQuad.
+  SubmitCompositorFrame(primary_child_support.get(), primary_child_passes,
+                        arraysize(primary_child_passes),
+                        primary_child_local_surface_id);
+
+  auto fallback_child_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryFrameSinkId2, kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId fallback_child_local_surface_id = allocator_.GenerateId();
+  SurfaceId fallback_child_surface_id(fallback_child_support->frame_sink_id(),
+                                      fallback_child_local_surface_id);
+
+  Quad fallback_child_quads[] = {Quad::SolidColorQuad(SK_ColorRED)};
+  Pass fallback_child_passes[] = {
+      Pass(fallback_child_quads, arraysize(fallback_child_quads))};
+
+  // Submit a cc::CompositorFrame to the fallback Surface containing a red
+  // SolidColorDrawQuad.
+  SubmitCompositorFrame(fallback_child_support.get(), fallback_child_passes,
+                        arraysize(fallback_child_passes),
+                        fallback_child_local_surface_id);
+
+  // Try to embed |primary_child_surface_id| and if unavailabe, embed
+  // |fallback_child_surface_id|.
+  Quad root_quads[] = {Quad::SurfaceQuad(primary_child_surface_id,
+                                         fallback_child_surface_id, 1.f)};
+  Pass root_passes[] = {Pass(root_quads, arraysize(root_quads))};
+
+  SubmitCompositorFrame(support_.get(), root_passes, arraysize(root_passes),
+                        root_local_surface_id_);
+
+  // The cc::CompositorFrame is submitted to |primary_child_surface_id|, so
+  // |fallback_child_surface_id| will not be used and we should see a green
+  // SolidColorDrawQuad.
+  Quad expected_quads1[] = {Quad::SolidColorQuad(SK_ColorGREEN)};
+  Pass expected_passes1[] = {Pass(expected_quads1, arraysize(expected_quads1))};
+
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  SurfaceId ids[] = {root_surface_id, primary_child_surface_id,
+                     fallback_child_surface_id};
+  AggregateAndVerify(expected_passes1, arraysize(expected_passes1), ids,
+                     arraysize(ids));
+
+  primary_child_support->EvictCurrentSurface();
+  fallback_child_support->EvictCurrentSurface();
+}
+
+TEST_F(SurfaceAggregatorValidSurfaceTest, CopyRequest) {
+  auto embedded_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId embedded_local_surface_id = allocator_.GenerateId();
+  SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
+                                embedded_local_surface_id);
+
+  Quad embedded_quads[] = {Quad::SolidColorQuad(SK_ColorGREEN)};
+  Pass embedded_passes[] = {Pass(embedded_quads, arraysize(embedded_quads))};
+
+  SubmitCompositorFrame(embedded_support.get(), embedded_passes,
+                        arraysize(embedded_passes), embedded_local_surface_id);
+  auto copy_request = cc::CopyOutputRequest::CreateEmptyRequest();
+  auto* copy_request_ptr = copy_request.get();
+  embedded_support->RequestCopyOfSurface(std::move(copy_request));
+
+  Quad root_quads[] = {
+      Quad::SolidColorQuad(SK_ColorWHITE),
+      Quad::SurfaceQuad(embedded_surface_id, InvalidSurfaceId(), 1.f),
+      Quad::SolidColorQuad(SK_ColorBLACK)};
+  Pass root_passes[] = {Pass(root_quads, arraysize(root_quads))};
+
+  SubmitCompositorFrame(support_.get(), root_passes, arraysize(root_passes),
+                        root_local_surface_id_);
+
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+  Quad expected_quads[] = {
+      Quad::SolidColorQuad(SK_ColorWHITE),
+      Quad::RenderPassQuad(aggregated_frame.render_pass_list[0]->id),
+      Quad::SolidColorQuad(SK_ColorBLACK)};
+  Pass expected_passes[] = {Pass(embedded_quads, arraysize(embedded_quads)),
+                            Pass(expected_quads, arraysize(expected_quads))};
+  TestPassesMatchExpectations(expected_passes, arraysize(expected_passes),
+                              &aggregated_frame.render_pass_list);
+  ASSERT_EQ(2u, aggregated_frame.render_pass_list.size());
+  ASSERT_EQ(1u, aggregated_frame.render_pass_list[0]->copy_requests.size());
+  DCHECK_EQ(copy_request_ptr,
+            aggregated_frame.render_pass_list[0]->copy_requests[0].get());
+
+  SurfaceId surface_ids[] = {root_surface_id, embedded_surface_id};
+  EXPECT_EQ(arraysize(surface_ids),
+            aggregator_.previous_contained_surfaces().size());
+  for (size_t i = 0; i < arraysize(surface_ids); i++) {
+    EXPECT_TRUE(
+        aggregator_.previous_contained_surfaces().find(surface_ids[i]) !=
+        aggregator_.previous_contained_surfaces().end());
+  }
+
+  embedded_support->EvictCurrentSurface();
+}
+
+// Root surface may contain copy requests.
+TEST_F(SurfaceAggregatorValidSurfaceTest, RootCopyRequest) {
+  auto embedded_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryFrameSinkId2, kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId embedded_local_surface_id = allocator_.GenerateId();
+  SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
+                                embedded_local_surface_id);
+
+  Quad embedded_quads[] = {Quad::SolidColorQuad(SK_ColorGREEN)};
+  Pass embedded_passes[] = {Pass(embedded_quads, arraysize(embedded_quads))};
+
+  SubmitCompositorFrame(embedded_support.get(), embedded_passes,
+                        arraysize(embedded_passes), embedded_local_surface_id);
+  auto copy_request(cc::CopyOutputRequest::CreateEmptyRequest());
+  auto* copy_request_ptr = copy_request.get();
+  auto copy_request2(cc::CopyOutputRequest::CreateEmptyRequest());
+  auto* copy_request2_ptr = copy_request2.get();
+
+  Quad root_quads[] = {
+      Quad::SolidColorQuad(SK_ColorWHITE),
+      Quad::SurfaceQuad(embedded_surface_id, InvalidSurfaceId(), 1.f),
+      Quad::SolidColorQuad(SK_ColorBLACK)};
+  Quad root_quads2[] = {Quad::SolidColorQuad(SK_ColorRED)};
+  Pass root_passes[] = {Pass(root_quads, arraysize(root_quads), 1),
+                        Pass(root_quads2, arraysize(root_quads2), 2)};
+  {
+    cc::CompositorFrame frame = cc::test::MakeEmptyCompositorFrame();
+    AddPasses(&frame.render_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+              arraysize(root_passes));
+    frame.render_pass_list[0]->copy_requests.push_back(std::move(copy_request));
+    frame.render_pass_list[1]->copy_requests.push_back(
+        std::move(copy_request2));
+
+    support_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
+  }
+
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+  Quad expected_quads[] = {Quad::SolidColorQuad(SK_ColorWHITE),
+                           Quad::SolidColorQuad(SK_ColorGREEN),
+                           Quad::SolidColorQuad(SK_ColorBLACK)};
+  Pass expected_passes[] = {Pass(expected_quads, arraysize(expected_quads)),
+                            Pass(root_quads2, arraysize(root_quads2))};
+  TestPassesMatchExpectations(expected_passes, arraysize(expected_passes),
+                              &aggregated_frame.render_pass_list);
+  ASSERT_EQ(2u, aggregated_frame.render_pass_list.size());
+  ASSERT_EQ(1u, aggregated_frame.render_pass_list[0]->copy_requests.size());
+  DCHECK_EQ(copy_request_ptr,
+            aggregated_frame.render_pass_list[0]->copy_requests[0].get());
+  ASSERT_EQ(1u, aggregated_frame.render_pass_list[1]->copy_requests.size());
+  DCHECK_EQ(copy_request2_ptr,
+            aggregated_frame.render_pass_list[1]->copy_requests[0].get());
+
+  SurfaceId surface_ids[] = {root_surface_id, embedded_surface_id};
+  EXPECT_EQ(arraysize(surface_ids),
+            aggregator_.previous_contained_surfaces().size());
+  for (size_t i = 0; i < arraysize(surface_ids); i++) {
+    EXPECT_TRUE(
+        aggregator_.previous_contained_surfaces().find(surface_ids[i]) !=
+        aggregator_.previous_contained_surfaces().end());
+  }
+
+  // Ensure copy requests have been removed from root surface.
+  const cc::CompositorFrame& original_frame =
+      manager_.surface_manager()
+          ->GetSurfaceForId(root_surface_id)
+          ->GetActiveFrame();
+  const auto& original_pass_list = original_frame.render_pass_list;
+  ASSERT_EQ(2u, original_pass_list.size());
+  DCHECK(original_pass_list[0]->copy_requests.empty());
+  DCHECK(original_pass_list[1]->copy_requests.empty());
+
+  embedded_support->EvictCurrentSurface();
+}
+
+TEST_F(SurfaceAggregatorValidSurfaceTest, UnreferencedSurface) {
+  auto embedded_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto parent_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryFrameSinkId2, kRootIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId embedded_local_surface_id = allocator_.GenerateId();
+  SurfaceId embedded_surface_id(embedded_support->frame_sink_id(),
+                                embedded_local_surface_id);
+  SurfaceId nonexistent_surface_id(support_->frame_sink_id(),
+                                   allocator_.GenerateId());
+
+  Quad embedded_quads[] = {Quad::SolidColorQuad(SK_ColorGREEN)};
+  Pass embedded_passes[] = {Pass(embedded_quads, arraysize(embedded_quads))};
+
+  SubmitCompositorFrame(embedded_support.get(), embedded_passes,
+                        arraysize(embedded_passes), embedded_local_surface_id);
+  auto copy_request(cc::CopyOutputRequest::CreateEmptyRequest());
+  auto* copy_request_ptr = copy_request.get();
+  embedded_support->RequestCopyOfSurface(std::move(copy_request));
+
+  LocalSurfaceId parent_local_surface_id = allocator_.GenerateId();
+  SurfaceId parent_surface_id(parent_support->frame_sink_id(),
+                              parent_local_surface_id);
+
+  Quad parent_quads[] = {
+      Quad::SolidColorQuad(SK_ColorGRAY),
+      Quad::SurfaceQuad(embedded_surface_id, InvalidSurfaceId(), 1.f),
+      Quad::SolidColorQuad(SK_ColorLTGRAY)};
+  Pass parent_passes[] = {Pass(parent_quads, arraysize(parent_quads))};
+
+  {
+    cc::CompositorFrame frame = cc::test::MakeEmptyCompositorFrame();
+
+    AddPasses(&frame.render_pass_list, gfx::Rect(SurfaceSize()), parent_passes,
+              arraysize(parent_passes));
+
+    frame.metadata.referenced_surfaces.push_back(embedded_surface_id);
+
+    parent_support->SubmitCompositorFrame(parent_local_surface_id,
+                                          std::move(frame));
+  }
+
+  Quad root_quads[] = {Quad::SolidColorQuad(SK_ColorWHITE),
+                       Quad::SolidColorQuad(SK_ColorBLACK)};
+  Pass root_passes[] = {Pass(root_quads, arraysize(root_quads))};
+
+  {
+    cc::CompositorFrame frame = cc::test::MakeEmptyCompositorFrame();
+    AddPasses(&frame.render_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+              arraysize(root_passes));
+
+    frame.metadata.referenced_surfaces.push_back(parent_surface_id);
+    // Reference to Surface ID of a Surface that doesn't exist should be
+    // included in previous_contained_surfaces, but otherwise ignored.
+    frame.metadata.referenced_surfaces.push_back(nonexistent_surface_id);
+
+    support_->SubmitCompositorFrame(root_local_surface_id_, std::move(frame));
+  }
+
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+  // First pass should come from surface that had a copy request but was not
+  // referenced directly. The second pass comes from the root surface.
+  // parent_quad should be ignored because it is neither referenced through a
+  // SurfaceDrawQuad nor has a copy request on it.
+  Pass expected_passes[] = {Pass(embedded_quads, arraysize(embedded_quads)),
+                            Pass(root_quads, arraysize(root_quads))};
+  TestPassesMatchExpectations(expected_passes, arraysize(expected_passes),
+                              &aggregated_frame.render_pass_list);
+  ASSERT_EQ(2u, aggregated_frame.render_pass_list.size());
+  ASSERT_EQ(1u, aggregated_frame.render_pass_list[0]->copy_requests.size());
+  DCHECK_EQ(copy_request_ptr,
+            aggregated_frame.render_pass_list[0]->copy_requests[0].get());
+
+  SurfaceId surface_ids[] = {
+      SurfaceId(support_->frame_sink_id(), root_local_surface_id_),
+      parent_surface_id, embedded_surface_id, nonexistent_surface_id};
+  EXPECT_EQ(arraysize(surface_ids),
+            aggregator_.previous_contained_surfaces().size());
+  for (size_t i = 0; i < arraysize(surface_ids); i++) {
+    EXPECT_TRUE(
+        aggregator_.previous_contained_surfaces().find(surface_ids[i]) !=
+        aggregator_.previous_contained_surfaces().end());
+  }
+
+  embedded_support->EvictCurrentSurface();
+  parent_support->EvictCurrentSurface();
+}
+
+// This tests referencing a surface that has multiple render passes.
+TEST_F(SurfaceAggregatorValidSurfaceTest, MultiPassSurfaceReference) {
+  LocalSurfaceId embedded_local_surface_id = child_allocator_.GenerateId();
+  SurfaceId embedded_surface_id(child_support_->frame_sink_id(),
+                                embedded_local_surface_id);
+
+  int pass_ids[] = {1, 2, 3};
+
+  Quad embedded_quads[][2] = {
+      {Quad::SolidColorQuad(1), Quad::SolidColorQuad(2)},
+      {Quad::SolidColorQuad(3), Quad::RenderPassQuad(pass_ids[0])},
+      {Quad::SolidColorQuad(4), Quad::RenderPassQuad(pass_ids[1])}};
+  Pass embedded_passes[] = {
+      Pass(embedded_quads[0], arraysize(embedded_quads[0]), pass_ids[0]),
+      Pass(embedded_quads[1], arraysize(embedded_quads[1]), pass_ids[1]),
+      Pass(embedded_quads[2], arraysize(embedded_quads[2]), pass_ids[2])};
+
+  SubmitCompositorFrame(child_support_.get(), embedded_passes,
+                        arraysize(embedded_passes), embedded_local_surface_id);
+
+  Quad root_quads[][2] = {
+      {Quad::SolidColorQuad(5), Quad::SolidColorQuad(6)},
+      {Quad::SurfaceQuad(embedded_surface_id, InvalidSurfaceId(), 1.f),
+       Quad::RenderPassQuad(pass_ids[0])},
+      {Quad::SolidColorQuad(7), Quad::RenderPassQuad(pass_ids[1])}};
+  Pass root_passes[] = {
+      Pass(root_quads[0], arraysize(root_quads[0]), pass_ids[0]),
+      Pass(root_quads[1], arraysize(root_quads[1]), pass_ids[1]),
+      Pass(root_quads[2], arraysize(root_quads[2]), pass_ids[2])};
+
+  SubmitCompositorFrame(support_.get(), root_passes, arraysize(root_passes),
+                        root_local_surface_id_);
+
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+  const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+  ASSERT_EQ(5u, aggregated_pass_list.size());
+  cc::RenderPassId actual_pass_ids[] = {
+      aggregated_pass_list[0]->id, aggregated_pass_list[1]->id,
+      aggregated_pass_list[2]->id, aggregated_pass_list[3]->id,
+      aggregated_pass_list[4]->id};
+  for (size_t i = 0; i < 5; ++i) {
+    for (size_t j = 0; j < i; ++j) {
+      EXPECT_NE(actual_pass_ids[i], actual_pass_ids[j]);
+    }
+  }
+
+  {
+    SCOPED_TRACE("First pass");
+    // The first pass will just be the first pass from the root surfaces quad
+    // with no render pass quads to remap.
+    TestPassMatchesExpectations(root_passes[0], aggregated_pass_list[0].get());
+  }
+
+  {
+    SCOPED_TRACE("Second pass");
+    // The next two passes will be from the embedded surface since we have to
+    // draw those passes before they are referenced from the render pass draw
+    // quad embedded into the root surface's second pass.
+    // First, there's the first embedded pass which doesn't reference anything
+    // else.
+    TestPassMatchesExpectations(embedded_passes[0],
+                                aggregated_pass_list[1].get());
+  }
+
+  {
+    SCOPED_TRACE("Third pass");
+    const auto& third_pass_quad_list = aggregated_pass_list[2]->quad_list;
+    ASSERT_EQ(2u, third_pass_quad_list.size());
+    TestQuadMatchesExpectations(embedded_quads[1][0],
+                                third_pass_quad_list.ElementAt(0));
+
+    // This render pass pass quad will reference the first pass from the
+    // embedded surface, which is the second pass in the aggregated frame.
+    ASSERT_EQ(cc::DrawQuad::RENDER_PASS,
+              third_pass_quad_list.ElementAt(1)->material);
+    const auto* third_pass_render_pass_draw_quad =
+        cc::RenderPassDrawQuad::MaterialCast(third_pass_quad_list.ElementAt(1));
+    EXPECT_EQ(actual_pass_ids[1],
+              third_pass_render_pass_draw_quad->render_pass_id);
+  }
+
+  {
+    SCOPED_TRACE("Fourth pass");
+    // The fourth pass will have aggregated quads from the root surface's second
+    // pass and the embedded surface's first pass.
+    const auto& fourth_pass_quad_list = aggregated_pass_list[3]->quad_list;
+    ASSERT_EQ(3u, fourth_pass_quad_list.size());
+
+    // The first quad will be the yellow quad from the embedded surface's last
+    // pass.
+    TestQuadMatchesExpectations(embedded_quads[2][0],
+                                fourth_pass_quad_list.ElementAt(0));
+
+    // The next quad will be a render pass quad referencing the second pass from
+    // the embedded surface, which is the third pass in the aggregated frame.
+    ASSERT_EQ(cc::DrawQuad::RENDER_PASS,
+              fourth_pass_quad_list.ElementAt(1)->material);
+    const auto* fourth_pass_first_render_pass_draw_quad =
+        cc::RenderPassDrawQuad::MaterialCast(
+            fourth_pass_quad_list.ElementAt(1));
+    EXPECT_EQ(actual_pass_ids[2],
+              fourth_pass_first_render_pass_draw_quad->render_pass_id);
+
+    // The last quad will be a render pass quad referencing the first pass from
+    // the root surface, which is the first pass overall.
+    ASSERT_EQ(cc::DrawQuad::RENDER_PASS,
+              fourth_pass_quad_list.ElementAt(2)->material);
+    const auto* fourth_pass_second_render_pass_draw_quad =
+        cc::RenderPassDrawQuad::MaterialCast(
+            fourth_pass_quad_list.ElementAt(2));
+    EXPECT_EQ(actual_pass_ids[0],
+              fourth_pass_second_render_pass_draw_quad->render_pass_id);
+  }
+
+  {
+    SCOPED_TRACE("Fifth pass");
+    const auto& fifth_pass_quad_list = aggregated_pass_list[4]->quad_list;
+    ASSERT_EQ(2u, fifth_pass_quad_list.size());
+
+    TestQuadMatchesExpectations(root_quads[2][0],
+                                fifth_pass_quad_list.ElementAt(0));
+
+    // The last quad in the last pass will reference the second pass from the
+    // root surface, which after aggregating is the fourth pass in the overall
+    // list.
+    ASSERT_EQ(cc::DrawQuad::RENDER_PASS,
+              fifth_pass_quad_list.ElementAt(1)->material);
+    const auto* fifth_pass_render_pass_draw_quad =
+        cc::RenderPassDrawQuad::MaterialCast(fifth_pass_quad_list.ElementAt(1));
+    EXPECT_EQ(actual_pass_ids[3],
+              fifth_pass_render_pass_draw_quad->render_pass_id);
+  }
+}
+
+// Tests an invalid surface reference in a frame. The surface quad should just
+// be dropped.
+TEST_F(SurfaceAggregatorValidSurfaceTest, InvalidSurfaceReference) {
+  Quad quads[] = {
+      Quad::SolidColorQuad(SK_ColorGREEN),
+      Quad::SurfaceQuad(InvalidSurfaceId(), InvalidSurfaceId(), 1.f),
+      Quad::SolidColorQuad(SK_ColorBLUE)};
+  Pass passes[] = {Pass(quads, arraysize(quads))};
+
+  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
+                        root_local_surface_id_);
+
+  Quad expected_quads[] = {Quad::SolidColorQuad(SK_ColorGREEN),
+                           Quad::SolidColorQuad(SK_ColorBLUE)};
+  Pass expected_passes[] = {Pass(expected_quads, arraysize(expected_quads))};
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  SurfaceId ids[] = {root_surface_id, InvalidSurfaceId()};
+
+  AggregateAndVerify(expected_passes, arraysize(expected_passes), ids,
+                     arraysize(ids));
+}
+
+// Tests a reference to a valid surface with no submitted frame. This quad
+// should also just be dropped.
+TEST_F(SurfaceAggregatorValidSurfaceTest, ValidSurfaceReferenceWithNoFrame) {
+  LocalSurfaceId empty_local_surface_id = allocator_.GenerateId();
+  SurfaceId surface_with_no_frame_id(support_->frame_sink_id(),
+                                     empty_local_surface_id);
+
+  Quad quads[] = {
+      Quad::SolidColorQuad(SK_ColorGREEN),
+      Quad::SurfaceQuad(surface_with_no_frame_id, InvalidSurfaceId(), 1.f),
+      Quad::SolidColorQuad(SK_ColorBLUE)};
+  Pass passes[] = {Pass(quads, arraysize(quads))};
+
+  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
+                        root_local_surface_id_);
+
+  Quad expected_quads[] = {Quad::SolidColorQuad(SK_ColorGREEN),
+                           Quad::SolidColorQuad(SK_ColorBLUE)};
+  Pass expected_passes[] = {Pass(expected_quads, arraysize(expected_quads))};
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  SurfaceId ids[] = {root_surface_id, surface_with_no_frame_id};
+  AggregateAndVerify(expected_passes, arraysize(expected_passes), ids,
+                     arraysize(ids));
+}
+
+// Tests a surface quad referencing itself, generating a trivial cycle.
+// The quad creating the cycle should be dropped from the final frame.
+TEST_F(SurfaceAggregatorValidSurfaceTest, SimpleCyclicalReference) {
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  Quad quads[] = {Quad::SurfaceQuad(root_surface_id, InvalidSurfaceId(), 1.f),
+                  Quad::SolidColorQuad(SK_ColorYELLOW)};
+  Pass passes[] = {Pass(quads, arraysize(quads))};
+
+  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
+                        root_local_surface_id_);
+
+  Quad expected_quads[] = {Quad::SolidColorQuad(SK_ColorYELLOW)};
+  Pass expected_passes[] = {Pass(expected_quads, arraysize(expected_quads))};
+  SurfaceId ids[] = {root_surface_id};
+  AggregateAndVerify(expected_passes, arraysize(expected_passes), ids,
+                     arraysize(ids));
+}
+
+// Tests a more complex cycle with one intermediate surface.
+TEST_F(SurfaceAggregatorValidSurfaceTest, TwoSurfaceCyclicalReference) {
+  LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
+  SurfaceId child_surface_id(child_support_->frame_sink_id(),
+                             child_local_surface_id);
+
+  Quad parent_quads[] = {
+      Quad::SolidColorQuad(SK_ColorBLUE),
+      Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f),
+      Quad::SolidColorQuad(SK_ColorCYAN)};
+  Pass parent_passes[] = {Pass(parent_quads, arraysize(parent_quads))};
+
+  SubmitCompositorFrame(support_.get(), parent_passes, arraysize(parent_passes),
+                        root_local_surface_id_);
+
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  Quad child_quads[] = {
+      Quad::SolidColorQuad(SK_ColorGREEN),
+      Quad::SurfaceQuad(root_surface_id, InvalidSurfaceId(), 1.f),
+      Quad::SolidColorQuad(SK_ColorMAGENTA)};
+  Pass child_passes[] = {Pass(child_quads, arraysize(child_quads))};
+
+  SubmitCompositorFrame(child_support_.get(), child_passes,
+                        arraysize(child_passes), child_local_surface_id);
+
+  // The child surface's reference to the root_surface_ will be dropped, so
+  // we'll end up with:
+  //   SK_ColorBLUE from the parent
+  //   SK_ColorGREEN from the child
+  //   SK_ColorMAGENTA from the child
+  //   SK_ColorCYAN from the parent
+  Quad expected_quads[] = {Quad::SolidColorQuad(SK_ColorBLUE),
+                           Quad::SolidColorQuad(SK_ColorGREEN),
+                           Quad::SolidColorQuad(SK_ColorMAGENTA),
+                           Quad::SolidColorQuad(SK_ColorCYAN)};
+  Pass expected_passes[] = {Pass(expected_quads, arraysize(expected_quads))};
+  SurfaceId ids[] = {root_surface_id, child_surface_id};
+  AggregateAndVerify(expected_passes, arraysize(expected_passes), ids,
+                     arraysize(ids));
+}
+
+// Tests that we map render pass IDs from different surfaces into a unified
+// namespace and update cc::RenderPassDrawQuad's id references to match.
+TEST_F(SurfaceAggregatorValidSurfaceTest, RenderPassIdMapping) {
+  LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
+  SurfaceId child_surface_id(child_support_->frame_sink_id(),
+                             child_local_surface_id);
+
+  cc::RenderPassId child_pass_id[] = {1u, 2u};
+  Quad child_quad[][1] = {{Quad::SolidColorQuad(SK_ColorGREEN)},
+                          {Quad::RenderPassQuad(child_pass_id[0])}};
+  Pass surface_passes[] = {
+      Pass(child_quad[0], arraysize(child_quad[0]), child_pass_id[0]),
+      Pass(child_quad[1], arraysize(child_quad[1]), child_pass_id[1])};
+
+  SubmitCompositorFrame(child_support_.get(), surface_passes,
+                        arraysize(surface_passes), child_local_surface_id);
+
+  // Pass IDs from the parent surface may collide with ones from the child.
+  cc::RenderPassId parent_pass_id[] = {3u, 2u};
+  Quad parent_quad[][1] = {
+      {Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)},
+      {Quad::RenderPassQuad(parent_pass_id[0])}};
+  Pass parent_passes[] = {
+      Pass(parent_quad[0], arraysize(parent_quad[0]), parent_pass_id[0]),
+      Pass(parent_quad[1], arraysize(parent_quad[1]), parent_pass_id[1])};
+
+  SubmitCompositorFrame(support_.get(), parent_passes, arraysize(parent_passes),
+                        root_local_surface_id_);
+
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+  const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+  ASSERT_EQ(3u, aggregated_pass_list.size());
+  cc::RenderPassId actual_pass_ids[] = {aggregated_pass_list[0]->id,
+                                        aggregated_pass_list[1]->id,
+                                        aggregated_pass_list[2]->id};
+  // Make sure the aggregated frame's pass IDs are all unique.
+  for (size_t i = 0; i < 3; ++i) {
+    for (size_t j = 0; j < i; ++j) {
+      EXPECT_NE(actual_pass_ids[j], actual_pass_ids[i])
+          << "pass ids " << i << " and " << j;
+    }
+  }
+
+  // Make sure the render pass quads reference the remapped pass IDs.
+  cc::DrawQuad* render_pass_quads[] = {
+      aggregated_pass_list[1]->quad_list.front(),
+      aggregated_pass_list[2]->quad_list.front()};
+  ASSERT_EQ(render_pass_quads[0]->material, cc::DrawQuad::RENDER_PASS);
+  EXPECT_EQ(actual_pass_ids[0],
+            cc::RenderPassDrawQuad::MaterialCast(render_pass_quads[0])
+                ->render_pass_id);
+
+  ASSERT_EQ(render_pass_quads[1]->material, cc::DrawQuad::RENDER_PASS);
+  EXPECT_EQ(actual_pass_ids[1],
+            cc::RenderPassDrawQuad::MaterialCast(render_pass_quads[1])
+                ->render_pass_id);
+}
+
+void AddSolidColorQuadWithBlendMode(const gfx::Size& size,
+                                    cc::RenderPass* pass,
+                                    const SkBlendMode blend_mode) {
+  const gfx::Transform layer_to_target_transform;
+  const gfx::Rect layer_rect(size);
+  const gfx::Rect visible_layer_rect(size);
+  const gfx::Rect clip_rect(size);
+
+  bool is_clipped = false;
+  float opacity = 1.f;
+
+  bool force_anti_aliasing_off = false;
+  auto* sqs = pass->CreateAndAppendSharedQuadState();
+  sqs->SetAll(layer_to_target_transform, layer_rect, visible_layer_rect,
+              clip_rect, is_clipped, opacity, blend_mode, 0);
+
+  auto* color_quad = pass->CreateAndAppendDrawQuad<cc::SolidColorDrawQuad>();
+  color_quad->SetNew(pass->shared_quad_state_list.back(), visible_layer_rect,
+                     visible_layer_rect, SK_ColorGREEN,
+                     force_anti_aliasing_off);
+}
+
+// This tests that we update shared quad state pointers correctly within
+// aggregated passes.  The shared quad state list on the aggregated pass will
+// include the shared quad states from each pass in one list so the quads will
+// end up pointed to shared quad state objects at different offsets. This test
+// uses the blend_mode value stored on the shared quad state to track the shared
+// quad state, but anything saved on the shared quad state would work.
+//
+// This test has 4 surfaces in the following structure:
+// root_surface -> quad with kClear_Mode,
+//                 [child_one_surface],
+//                 quad with kDstOver_Mode,
+//                 [child_two_surface],
+//                 quad with kDstIn_Mode
+// child_one_surface -> quad with kSrc_Mode,
+//                      [grandchild_surface],
+//                      quad with kSrcOver_Mode
+// child_two_surface -> quad with kSrcIn_Mode
+// grandchild_surface -> quad with kDst_Mode
+//
+// Resulting in the following aggregated pass:
+//  quad_root_0       - blend_mode kClear_Mode
+//  quad_child_one_0  - blend_mode kSrc_Mode
+//  quad_grandchild_0 - blend_mode kDst_Mode
+//  quad_child_one_1  - blend_mode kSrcOver_Mode
+//  quad_root_1       - blend_mode kDstOver_Mode
+//  quad_child_two_0  - blend_mode kSrcIn_Mode
+//  quad_root_2       - blend_mode kDstIn_Mode
+TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateSharedQuadStateProperties) {
+  const SkBlendMode blend_modes[] = {
+      SkBlendMode::kClear,    // 0
+      SkBlendMode::kSrc,      // 1
+      SkBlendMode::kDst,      // 2
+      SkBlendMode::kSrcOver,  // 3
+      SkBlendMode::kDstOver,  // 4
+      SkBlendMode::kSrcIn,    // 5
+      SkBlendMode::kDstIn,    // 6
+  };
+  auto grandchild_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto child_one_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryFrameSinkId2, kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto child_two_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryFrameSinkId3, kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  int pass_id = 1;
+  LocalSurfaceId grandchild_local_surface_id = allocator_.GenerateId();
+  SurfaceId grandchild_surface_id(grandchild_support->frame_sink_id(),
+                                  grandchild_local_surface_id);
+
+  auto grandchild_pass = cc::RenderPass::Create();
+  gfx::Rect output_rect(SurfaceSize());
+  gfx::Rect damage_rect(SurfaceSize());
+  gfx::Transform transform_to_root_target;
+  grandchild_pass->SetNew(pass_id, output_rect, damage_rect,
+                          transform_to_root_target);
+  AddSolidColorQuadWithBlendMode(SurfaceSize(), grandchild_pass.get(),
+                                 blend_modes[2]);
+  QueuePassAsFrame(std::move(grandchild_pass), grandchild_local_surface_id,
+                   grandchild_support.get());
+
+  LocalSurfaceId child_one_local_surface_id = allocator_.GenerateId();
+  SurfaceId child_one_surface_id(child_one_support->frame_sink_id(),
+                                 child_one_local_surface_id);
+
+  auto child_one_pass = cc::RenderPass::Create();
+  child_one_pass->SetNew(pass_id, output_rect, damage_rect,
+                         transform_to_root_target);
+  AddSolidColorQuadWithBlendMode(SurfaceSize(), child_one_pass.get(),
+                                 blend_modes[1]);
+  auto* grandchild_surface_quad =
+      child_one_pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
+  grandchild_surface_quad->SetNew(
+      child_one_pass->shared_quad_state_list.back(), gfx::Rect(SurfaceSize()),
+      gfx::Rect(SurfaceSize()), grandchild_surface_id,
+      cc::SurfaceDrawQuadType::PRIMARY, nullptr);
+  AddSolidColorQuadWithBlendMode(SurfaceSize(), child_one_pass.get(),
+                                 blend_modes[3]);
+  QueuePassAsFrame(std::move(child_one_pass), child_one_local_surface_id,
+                   child_one_support.get());
+
+  LocalSurfaceId child_two_local_surface_id = allocator_.GenerateId();
+  SurfaceId child_two_surface_id(child_two_support->frame_sink_id(),
+                                 child_two_local_surface_id);
+
+  auto child_two_pass = cc::RenderPass::Create();
+  child_two_pass->SetNew(pass_id, output_rect, damage_rect,
+                         transform_to_root_target);
+  AddSolidColorQuadWithBlendMode(SurfaceSize(), child_two_pass.get(),
+                                 blend_modes[5]);
+  QueuePassAsFrame(std::move(child_two_pass), child_two_local_surface_id,
+                   child_two_support.get());
+
+  auto root_pass = cc::RenderPass::Create();
+  root_pass->SetNew(pass_id, output_rect, damage_rect,
+                    transform_to_root_target);
+
+  AddSolidColorQuadWithBlendMode(SurfaceSize(), root_pass.get(),
+                                 blend_modes[0]);
+  auto* child_one_surface_quad =
+      root_pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
+  child_one_surface_quad->SetNew(root_pass->shared_quad_state_list.back(),
+                                 gfx::Rect(SurfaceSize()),
+                                 gfx::Rect(SurfaceSize()), child_one_surface_id,
+                                 cc::SurfaceDrawQuadType::PRIMARY, nullptr);
+  AddSolidColorQuadWithBlendMode(SurfaceSize(), root_pass.get(),
+                                 blend_modes[4]);
+  auto* child_two_surface_quad =
+      root_pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
+  child_two_surface_quad->SetNew(root_pass->shared_quad_state_list.back(),
+                                 gfx::Rect(SurfaceSize()),
+                                 gfx::Rect(SurfaceSize()), child_two_surface_id,
+                                 cc::SurfaceDrawQuadType::PRIMARY, nullptr);
+  AddSolidColorQuadWithBlendMode(SurfaceSize(), root_pass.get(),
+                                 blend_modes[6]);
+
+  QueuePassAsFrame(std::move(root_pass), root_local_surface_id_,
+                   support_.get());
+
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+  const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+  ASSERT_EQ(1u, aggregated_pass_list.size());
+
+  const auto& aggregated_quad_list = aggregated_pass_list[0]->quad_list;
+
+  ASSERT_EQ(7u, aggregated_quad_list.size());
+
+  for (auto iter = aggregated_quad_list.cbegin();
+       iter != aggregated_quad_list.cend(); ++iter) {
+    EXPECT_EQ(blend_modes[iter.index()], iter->shared_quad_state->blend_mode)
+        << iter.index();
+  }
+
+  grandchild_support->EvictCurrentSurface();
+  child_one_support->EvictCurrentSurface();
+  child_two_support->EvictCurrentSurface();
+}
+
+// This tests that when aggregating a frame with multiple render passes that we
+// map the transforms for the root pass but do not modify the transform on child
+// passes.
+//
+// The root surface has one pass with a surface quad transformed by +10 in the y
+// direction.
+//
+// The middle surface has one pass with a surface quad scaled by 2 in the x
+// and 3 in the y directions.
+//
+// The child surface has two passes. The first pass has a quad with a transform
+// of +5 in the x direction. The second pass has a reference to the first pass'
+// pass id and a transform of +8 in the x direction.
+//
+// After aggregation, the child surface's root pass quad should have all
+// transforms concatenated for a total transform of +23 x, +10 y. The
+// contributing render pass' transform in the aggregate frame should not be
+// affected.
+TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateMultiplePassWithTransform) {
+  auto middle_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryMiddleFrameSinkId, kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  // Innermost child surface.
+  LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
+  SurfaceId child_surface_id(child_support_->frame_sink_id(),
+                             child_local_surface_id);
+  {
+    int child_pass_id[] = {1, 2};
+    Quad child_quads[][1] = {
+        {Quad::SolidColorQuad(SK_ColorGREEN)},
+        {Quad::RenderPassQuad(child_pass_id[0])},
+    };
+    Pass child_passes[] = {
+        Pass(child_quads[0], arraysize(child_quads[0]), child_pass_id[0]),
+        Pass(child_quads[1], arraysize(child_quads[1]), child_pass_id[1])};
+
+    cc::CompositorFrame child_frame = cc::test::MakeEmptyCompositorFrame();
+    AddPasses(&child_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+              child_passes, arraysize(child_passes));
+
+    auto* child_nonroot_pass = child_frame.render_pass_list[0].get();
+    child_nonroot_pass->transform_to_root_target.Translate(8, 0);
+    auto* child_nonroot_pass_sqs =
+        child_nonroot_pass->shared_quad_state_list.front();
+    child_nonroot_pass_sqs->quad_to_target_transform.Translate(5, 0);
+
+    auto* child_root_pass = child_frame.render_pass_list[1].get();
+    auto* child_root_pass_sqs = child_root_pass->shared_quad_state_list.front();
+    child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
+    child_root_pass_sqs->is_clipped = true;
+    child_root_pass_sqs->clip_rect = gfx::Rect(0, 0, 5, 5);
+
+    child_support_->SubmitCompositorFrame(child_local_surface_id,
+                                          std::move(child_frame));
+  }
+
+  // Middle child surface.
+  LocalSurfaceId middle_local_surface_id = allocator_.GenerateId();
+  SurfaceId middle_surface_id(middle_support->frame_sink_id(),
+                              middle_local_surface_id);
+  {
+    Quad middle_quads[] = {
+        Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
+    Pass middle_passes[] = {
+        Pass(middle_quads, arraysize(middle_quads)),
+    };
+
+    cc::CompositorFrame middle_frame = cc::test::MakeEmptyCompositorFrame();
+    AddPasses(&middle_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+              middle_passes, arraysize(middle_passes));
+
+    auto* middle_root_pass = middle_frame.render_pass_list[0].get();
+    middle_root_pass->quad_list.ElementAt(0)->visible_rect =
+        gfx::Rect(0, 1, 100, 7);
+    auto* middle_root_pass_sqs =
+        middle_root_pass->shared_quad_state_list.front();
+    middle_root_pass_sqs->quad_to_target_transform.Scale(2, 3);
+
+    middle_support->SubmitCompositorFrame(middle_local_surface_id,
+                                          std::move(middle_frame));
+  }
+
+  // Root surface.
+  Quad secondary_quads[] = {
+      Quad::SolidColorQuad(1),
+      Quad::SurfaceQuad(middle_surface_id, InvalidSurfaceId(), 1.f)};
+  Quad root_quads[] = {Quad::SolidColorQuad(1)};
+  Pass root_passes[] = {Pass(secondary_quads, arraysize(secondary_quads)),
+                        Pass(root_quads, arraysize(root_quads))};
+
+  cc::CompositorFrame root_frame = cc::test::MakeEmptyCompositorFrame();
+  AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+            arraysize(root_passes));
+
+  root_frame.render_pass_list[0]
+      ->shared_quad_state_list.front()
+      ->quad_to_target_transform.Translate(0, 7);
+  root_frame.render_pass_list[0]
+      ->shared_quad_state_list.ElementAt(1)
+      ->quad_to_target_transform.Translate(0, 10);
+  root_frame.render_pass_list[0]->quad_list.ElementAt(1)->visible_rect =
+      gfx::Rect(0, 0, 8, 100);
+
+  root_frame.render_pass_list[0]->transform_to_root_target.Translate(10, 5);
+
+  support_->SubmitCompositorFrame(root_local_surface_id_,
+                                  std::move(root_frame));
+
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+  const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+  ASSERT_EQ(3u, aggregated_pass_list.size());
+
+  ASSERT_EQ(1u, aggregated_pass_list[0]->shared_quad_state_list.size());
+
+  // The first pass should have one shared quad state for the one solid color
+  // quad.
+  EXPECT_EQ(1u, aggregated_pass_list[0]->shared_quad_state_list.size());
+  // The second pass should have just two shared quad states. We'll
+  // verify the properties through the quads.
+  EXPECT_EQ(2u, aggregated_pass_list[1]->shared_quad_state_list.size());
+
+  EXPECT_EQ(1u, aggregated_pass_list[2]->shared_quad_state_list.size());
+
+  auto* aggregated_first_pass_sqs =
+      aggregated_pass_list[0]->shared_quad_state_list.front();
+
+  // The first pass's transform should be unaffected by the embedding and still
+  // be a translation by +5 in the x direction.
+  gfx::Transform expected_aggregated_first_pass_sqs_transform;
+  expected_aggregated_first_pass_sqs_transform.Translate(5, 0);
+  EXPECT_EQ(expected_aggregated_first_pass_sqs_transform.ToString(),
+            aggregated_first_pass_sqs->quad_to_target_transform.ToString());
+
+  // The first pass's transform to the root target should include the aggregated
+  // transform, including the transform from the child pass to the root.
+  gfx::Transform expected_first_pass_transform_to_root_target;
+  expected_first_pass_transform_to_root_target.Translate(10, 5);
+  expected_first_pass_transform_to_root_target.Translate(0, 10);
+  expected_first_pass_transform_to_root_target.Scale(2, 3);
+  expected_first_pass_transform_to_root_target.Translate(8, 0);
+  EXPECT_EQ(expected_first_pass_transform_to_root_target.ToString(),
+            aggregated_pass_list[0]->transform_to_root_target.ToString());
+
+  ASSERT_EQ(2u, aggregated_pass_list[1]->quad_list.size());
+
+  gfx::Transform expected_root_pass_quad_transforms[2];
+  // The first quad in the root pass is the solid color quad from the original
+  // root surface. Its transform should be unaffected by the aggregation and
+  // still be +7 in the y direction.
+  expected_root_pass_quad_transforms[0].Translate(0, 7);
+  // The second quad in the root pass is aggregated from the child surface so
+  // its transform should be the combination of its original translation
+  // (0, 10), the middle surface draw quad's scale of (2, 3), and the
+  // child surface draw quad's translation (8, 0).
+  expected_root_pass_quad_transforms[1].Translate(0, 10);
+  expected_root_pass_quad_transforms[1].Scale(2, 3);
+  expected_root_pass_quad_transforms[1].Translate(8, 0);
+
+  for (auto iter = aggregated_pass_list[1]->quad_list.cbegin();
+       iter != aggregated_pass_list[1]->quad_list.cend(); ++iter) {
+    EXPECT_EQ(expected_root_pass_quad_transforms[iter.index()].ToString(),
+              iter->shared_quad_state->quad_to_target_transform.ToString())
+        << iter.index();
+  }
+
+  EXPECT_TRUE(
+      aggregated_pass_list[1]->shared_quad_state_list.ElementAt(1)->is_clipped);
+
+  // The second quad in the root pass is aggregated from the child, so its
+  // clip rect must be transformed by the child's translation/scale and
+  // clipped be the visible_rects for both children.
+  EXPECT_EQ(gfx::Rect(0, 13, 8, 12).ToString(),
+            aggregated_pass_list[1]
+                ->shared_quad_state_list.ElementAt(1)
+                ->clip_rect.ToString());
+
+  middle_support->EvictCurrentSurface();
+}
+
+// Tests that damage rects are aggregated correctly when surfaces change.
+TEST_F(SurfaceAggregatorValidSurfaceTest, AggregateDamageRect) {
+  auto parent_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryMiddleFrameSinkId, kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  Quad child_quads[] = {Quad::RenderPassQuad(1)};
+  Pass child_passes[] = {Pass(child_quads, arraysize(child_quads), 1)};
+
+  cc::CompositorFrame child_frame = cc::test::MakeEmptyCompositorFrame();
+  AddPasses(&child_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+            child_passes, arraysize(child_passes));
+
+  auto* child_root_pass = child_frame.render_pass_list[0].get();
+  auto* child_root_pass_sqs = child_root_pass->shared_quad_state_list.front();
+  child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
+
+  LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
+  SurfaceId child_surface_id(child_support_->frame_sink_id(),
+                             child_local_surface_id);
+  child_support_->SubmitCompositorFrame(child_local_surface_id,
+                                        std::move(child_frame));
+
+  Quad parent_surface_quads[] = {
+      Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
+  Pass parent_surface_passes[] = {
+      Pass(parent_surface_quads, arraysize(parent_surface_quads), 1)};
+
+  // Parent surface is only used to test if the transform is applied correctly
+  // to the child surface's damage.
+  cc::CompositorFrame parent_surface_frame =
+      cc::test::MakeEmptyCompositorFrame();
+  AddPasses(&parent_surface_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+            parent_surface_passes, arraysize(parent_surface_passes));
+
+  LocalSurfaceId parent_local_surface_id = allocator_.GenerateId();
+  SurfaceId parent_surface_id(parent_support->frame_sink_id(),
+                              parent_local_surface_id);
+  parent_support->SubmitCompositorFrame(parent_local_surface_id,
+                                        std::move(parent_surface_frame));
+
+  Quad root_surface_quads[] = {
+      Quad::SurfaceQuad(parent_surface_id, InvalidSurfaceId(), 1.f)};
+  Quad root_render_pass_quads[] = {Quad::RenderPassQuad(1)};
+
+  Pass root_passes[] = {
+      Pass(root_surface_quads, arraysize(root_surface_quads), 1),
+      Pass(root_render_pass_quads, arraysize(root_render_pass_quads), 2)};
+
+  cc::CompositorFrame root_frame = cc::test::MakeEmptyCompositorFrame();
+  AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+            arraysize(root_passes));
+
+  root_frame.render_pass_list[0]
+      ->shared_quad_state_list.front()
+      ->quad_to_target_transform.Translate(0, 10);
+  root_frame.render_pass_list[0]->damage_rect = gfx::Rect(5, 5, 10, 10);
+  root_frame.render_pass_list[1]->damage_rect = gfx::Rect(5, 5, 100, 100);
+
+  support_->SubmitCompositorFrame(root_local_surface_id_,
+                                  std::move(root_frame));
+
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+  const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+  ASSERT_EQ(2u, aggregated_pass_list.size());
+
+  // Damage rect for first aggregation should contain entire root surface.
+  EXPECT_TRUE(
+      aggregated_pass_list[1]->damage_rect.Contains(gfx::Rect(SurfaceSize())));
+
+  {
+    cc::CompositorFrame child_frame = cc::test::MakeEmptyCompositorFrame();
+    AddPasses(&child_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+              child_passes, arraysize(child_passes));
+
+    auto* child_root_pass = child_frame.render_pass_list[0].get();
+    auto* child_root_pass_sqs = child_root_pass->shared_quad_state_list.front();
+    child_root_pass_sqs->quad_to_target_transform.Translate(8, 0);
+    child_root_pass->damage_rect = gfx::Rect(10, 10, 10, 10);
+
+    child_support_->SubmitCompositorFrame(child_local_surface_id,
+                                          std::move(child_frame));
+
+    SurfaceId root_surface_id(support_->frame_sink_id(),
+                              root_local_surface_id_);
+    cc::CompositorFrame aggregated_frame =
+        aggregator_.Aggregate(root_surface_id);
+
+    const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+    ASSERT_EQ(2u, aggregated_pass_list.size());
+
+    // Outer surface didn't change, so transformed inner damage rect should be
+    // used.
+    EXPECT_EQ(gfx::Rect(10, 20, 10, 10).ToString(),
+              aggregated_pass_list[1]->damage_rect.ToString());
+  }
+
+  {
+    cc::CompositorFrame root_frame = cc::test::MakeEmptyCompositorFrame();
+    AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+              root_passes, arraysize(root_passes));
+
+    root_frame.render_pass_list[0]
+        ->shared_quad_state_list.front()
+        ->quad_to_target_transform.Translate(0, 10);
+    root_frame.render_pass_list[0]->damage_rect = gfx::Rect(0, 0, 1, 1);
+
+    support_->SubmitCompositorFrame(root_local_surface_id_,
+                                    std::move(root_frame));
+  }
+
+  {
+    cc::CompositorFrame root_frame = cc::test::MakeEmptyCompositorFrame();
+    AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+              root_passes, arraysize(root_passes));
+
+    root_frame.render_pass_list[0]
+        ->shared_quad_state_list.front()
+        ->quad_to_target_transform.Translate(0, 10);
+    root_frame.render_pass_list[0]->damage_rect = gfx::Rect(1, 1, 1, 1);
+
+    support_->SubmitCompositorFrame(root_local_surface_id_,
+                                    std::move(root_frame));
+
+    SurfaceId root_surface_id(support_->frame_sink_id(),
+                              root_local_surface_id_);
+    cc::CompositorFrame aggregated_frame =
+        aggregator_.Aggregate(root_surface_id);
+
+    const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+    ASSERT_EQ(2u, aggregated_pass_list.size());
+
+    // The root surface was enqueued without being aggregated once, so it should
+    // be treated as completely damaged.
+    EXPECT_TRUE(aggregated_pass_list[1]->damage_rect.Contains(
+        gfx::Rect(SurfaceSize())));
+  }
+
+  // No Surface changed, so no damage should be given.
+  {
+    SurfaceId root_surface_id(support_->frame_sink_id(),
+                              root_local_surface_id_);
+    cc::CompositorFrame aggregated_frame =
+        aggregator_.Aggregate(root_surface_id);
+
+    const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+    ASSERT_EQ(2u, aggregated_pass_list.size());
+
+    EXPECT_TRUE(aggregated_pass_list[1]->damage_rect.IsEmpty());
+  }
+
+  // SetFullDamageRectForSurface should cause the entire output to be
+  // marked as damaged.
+  {
+    aggregator_.SetFullDamageForSurface(root_surface_id);
+    cc::CompositorFrame aggregated_frame =
+        aggregator_.Aggregate(root_surface_id);
+
+    const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+    ASSERT_EQ(2u, aggregated_pass_list.size());
+
+    EXPECT_TRUE(aggregated_pass_list[1]->damage_rect.Contains(
+        gfx::Rect(SurfaceSize())));
+  }
+
+  parent_support->EvictCurrentSurface();
+}
+
+// Check that damage is correctly calculated for surfaces.
+TEST_F(SurfaceAggregatorValidSurfaceTest, SwitchSurfaceDamage) {
+  Quad root_render_pass_quads[] = {Quad::SolidColorQuad(1)};
+
+  Pass root_passes[] = {
+      Pass(root_render_pass_quads, arraysize(root_render_pass_quads), 2)};
+
+  cc::CompositorFrame root_frame = cc::test::MakeEmptyCompositorFrame();
+  AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+            arraysize(root_passes));
+
+  root_frame.render_pass_list[0]->damage_rect = gfx::Rect(5, 5, 100, 100);
+
+  support_->SubmitCompositorFrame(root_local_surface_id_,
+                                  std::move(root_frame));
+
+  {
+    SurfaceId root_surface_id(support_->frame_sink_id(),
+                              root_local_surface_id_);
+    cc::CompositorFrame aggregated_frame =
+        aggregator_.Aggregate(root_surface_id);
+
+    const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+    ASSERT_EQ(1u, aggregated_pass_list.size());
+
+    // Damage rect for first aggregation should contain entire root surface.
+    EXPECT_TRUE(aggregated_pass_list[0]->damage_rect.Contains(
+        gfx::Rect(SurfaceSize())));
+  }
+
+  LocalSurfaceId second_root_local_surface_id = allocator_.GenerateId();
+  SurfaceId second_root_surface_id(support_->frame_sink_id(),
+                                   second_root_local_surface_id);
+  {
+    Quad root_render_pass_quads[] = {Quad::SolidColorQuad(1)};
+
+    Pass root_passes[] = {
+        Pass(root_render_pass_quads, arraysize(root_render_pass_quads), 2)};
+
+    cc::CompositorFrame root_frame = cc::test::MakeEmptyCompositorFrame();
+    AddPasses(&root_frame.render_pass_list, gfx::Rect(SurfaceSize()),
+              root_passes, arraysize(root_passes));
+
+    root_frame.render_pass_list[0]->damage_rect = gfx::Rect(1, 2, 3, 4);
+
+    support_->SubmitCompositorFrame(second_root_local_surface_id,
+                                    std::move(root_frame));
+  }
+  {
+    cc::CompositorFrame aggregated_frame =
+        aggregator_.Aggregate(second_root_surface_id);
+
+    const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+    ASSERT_EQ(1u, aggregated_pass_list.size());
+
+    EXPECT_EQ(gfx::Rect(1, 2, 3, 4), aggregated_pass_list[0]->damage_rect);
+  }
+  {
+    cc::CompositorFrame aggregated_frame =
+        aggregator_.Aggregate(second_root_surface_id);
+
+    const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+    ASSERT_EQ(1u, aggregated_pass_list.size());
+
+    // No new frame, so no new damage.
+    EXPECT_TRUE(aggregated_pass_list[0]->damage_rect.IsEmpty());
+  }
+}
+
+class SurfaceAggregatorPartialSwapTest
+    : public SurfaceAggregatorValidSurfaceTest {
+ public:
+  SurfaceAggregatorPartialSwapTest()
+      : SurfaceAggregatorValidSurfaceTest(true) {}
+};
+
+// Tests that quads outside the damage rect are ignored.
+TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) {
+  LocalSurfaceId child_local_surface_id = allocator_.GenerateId();
+  SurfaceId child_surface_id(child_support_->frame_sink_id(),
+                             child_local_surface_id);
+  // The child surface has three quads, one with a visible rect of 13,13 4x4 and
+  // the other other with a visible rect of 10,10 2x2 (relative to root target
+  // space), and one with a non-invertible transform.
+  {
+    int child_pass_id = 1;
+    Quad child_quads1[] = {Quad::RenderPassQuad(child_pass_id)};
+    Quad child_quads2[] = {Quad::RenderPassQuad(child_pass_id)};
+    Quad child_quads3[] = {Quad::RenderPassQuad(child_pass_id)};
+    Pass child_passes[] = {
+        Pass(child_quads1, arraysize(child_quads1), child_pass_id),
+        Pass(child_quads2, arraysize(child_quads2), child_pass_id),
+        Pass(child_quads3, arraysize(child_quads2), child_pass_id)};
+
+    cc::RenderPassList child_pass_list;
+    AddPasses(&child_pass_list, gfx::Rect(SurfaceSize()), child_passes,
+              arraysize(child_passes));
+
+    child_pass_list[0]->quad_list.ElementAt(0)->visible_rect =
+        gfx::Rect(1, 1, 2, 2);
+    auto* child_sqs = child_pass_list[0]->shared_quad_state_list.ElementAt(0u);
+    child_sqs->quad_to_target_transform.Translate(1, 1);
+    child_sqs->quad_to_target_transform.Scale(2, 2);
+
+    child_pass_list[1]->quad_list.ElementAt(0)->visible_rect =
+        gfx::Rect(0, 0, 2, 2);
+
+    auto* child_noninvertible_sqs =
+        child_pass_list[2]->shared_quad_state_list.ElementAt(0u);
+    child_noninvertible_sqs->quad_to_target_transform.matrix().setDouble(0, 0,
+                                                                         0.0);
+    EXPECT_FALSE(
+        child_noninvertible_sqs->quad_to_target_transform.IsInvertible());
+    child_pass_list[2]->quad_list.ElementAt(0)->visible_rect =
+        gfx::Rect(0, 0, 2, 2);
+
+    SubmitPassListAsFrame(child_support_.get(), child_local_surface_id,
+                          &child_pass_list);
+  }
+
+  {
+    Quad root_quads[] = {
+        Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
+
+    Pass root_passes[] = {Pass(root_quads, arraysize(root_quads))};
+
+    cc::RenderPassList root_pass_list;
+    AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+              arraysize(root_passes));
+
+    auto* root_pass = root_pass_list[0].get();
+    root_pass->shared_quad_state_list.front()
+        ->quad_to_target_transform.Translate(10, 10);
+    root_pass->damage_rect = gfx::Rect(0, 0, 1, 1);
+
+    SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
+                          &root_pass_list);
+  }
+
+  SurfaceId root_surface_id(support_->frame_sink_id(), root_local_surface_id_);
+  cc::CompositorFrame aggregated_frame = aggregator_.Aggregate(root_surface_id);
+
+  const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+  ASSERT_EQ(3u, aggregated_pass_list.size());
+
+  // Damage rect for first aggregation should contain entire root surface.
+  EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[2]->damage_rect);
+  EXPECT_EQ(1u, aggregated_pass_list[0]->quad_list.size());
+  EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size());
+  EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size());
+
+  // Create a root surface with a smaller damage rect.
+  {
+    Quad root_quads[] = {
+        Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
+
+    Pass root_passes[] = {Pass(root_quads, arraysize(root_quads))};
+
+    cc::RenderPassList root_pass_list;
+    AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+              arraysize(root_passes));
+
+    auto* root_pass = root_pass_list[0].get();
+    root_pass->shared_quad_state_list.front()
+        ->quad_to_target_transform.Translate(10, 10);
+    root_pass->damage_rect = gfx::Rect(10, 10, 2, 2);
+    SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
+                          &root_pass_list);
+  }
+
+  {
+    cc::CompositorFrame aggregated_frame =
+        aggregator_.Aggregate(root_surface_id);
+
+    const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+    ASSERT_EQ(3u, aggregated_pass_list.size());
+
+    // Only first quad from surface is inside damage rect and should be
+    // included.
+    EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[2]->damage_rect);
+    EXPECT_EQ(0u, aggregated_pass_list[0]->quad_list.size());
+    EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size());
+    EXPECT_EQ(gfx::Rect(0, 0, 2, 2),
+              aggregated_pass_list[1]->quad_list.back()->visible_rect);
+    EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size());
+  }
+
+  // New child frame has same content and no damage, but has a
+  // CopyOutputRequest.
+  {
+    int child_pass_ids[] = {1, 2};
+    Quad child_quads1[] = {Quad::SolidColorQuad(1)};
+    Quad child_quads2[] = {Quad::RenderPassQuad(child_pass_ids[0])};
+    Pass child_passes[] = {
+        Pass(child_quads1, arraysize(child_quads1), child_pass_ids[0]),
+        Pass(child_quads2, arraysize(child_quads2), child_pass_ids[1])};
+
+    cc::RenderPassList child_pass_list;
+    AddPasses(&child_pass_list, gfx::Rect(SurfaceSize()), child_passes,
+              arraysize(child_passes));
+
+    child_pass_list[0]->quad_list.ElementAt(0)->visible_rect =
+        gfx::Rect(1, 1, 2, 2);
+    auto* child_sqs = child_pass_list[0]->shared_quad_state_list.ElementAt(0u);
+    child_sqs->quad_to_target_transform.Translate(1, 1);
+    child_sqs->quad_to_target_transform.Scale(2, 2);
+
+    child_pass_list[1]->quad_list.ElementAt(0)->visible_rect =
+        gfx::Rect(0, 0, 2, 2);
+
+    auto* child_root_pass = child_pass_list[1].get();
+
+    child_root_pass->copy_requests.push_back(
+        cc::CopyOutputRequest::CreateEmptyRequest());
+    child_root_pass->damage_rect = gfx::Rect();
+    SubmitPassListAsFrame(child_support_.get(), child_local_surface_id,
+                          &child_pass_list);
+  }
+
+  {
+    cc::CompositorFrame aggregated_frame =
+        aggregator_.Aggregate(root_surface_id);
+
+    const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+    // Output frame should have no damage, but all quads included.
+    ASSERT_EQ(3u, aggregated_pass_list.size());
+
+    EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[0]->damage_rect);
+    EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[1]->damage_rect);
+    EXPECT_TRUE(aggregated_pass_list[2]->damage_rect.IsEmpty());
+    ASSERT_EQ(1u, aggregated_pass_list[0]->quad_list.size());
+    ASSERT_EQ(1u, aggregated_pass_list[1]->quad_list.size());
+    EXPECT_EQ(gfx::Rect(1, 1, 2, 2),
+              aggregated_pass_list[0]->quad_list.ElementAt(0)->visible_rect);
+    EXPECT_EQ(gfx::Rect(0, 0, 2, 2),
+              aggregated_pass_list[1]->quad_list.ElementAt(0)->visible_rect);
+    ASSERT_EQ(1u, aggregated_pass_list[2]->quad_list.size());
+  }
+
+  {
+    cc::CompositorFrame aggregated_frame =
+        aggregator_.Aggregate(root_surface_id);
+
+    const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+    // There were no changes since last aggregation, so output should be empty
+    // and have no damage.
+    ASSERT_EQ(1u, aggregated_pass_list.size());
+    EXPECT_TRUE(aggregated_pass_list[0]->damage_rect.IsEmpty());
+    ASSERT_EQ(0u, aggregated_pass_list[0]->quad_list.size());
+  }
+
+  // Root surface has smaller damage rect, but filter on render pass means all
+  // of it and its descendant passes should be aggregated.
+  {
+    int root_pass_ids[] = {1, 2, 3};
+    Quad root_quads1[] = {
+        Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
+    Quad root_quads2[] = {Quad::RenderPassQuad(root_pass_ids[0])};
+    Quad root_quads3[] = {Quad::RenderPassQuad(root_pass_ids[1])};
+    Pass root_passes[] = {
+        Pass(root_quads1, arraysize(root_quads1), root_pass_ids[0]),
+        Pass(root_quads2, arraysize(root_quads2), root_pass_ids[1]),
+        Pass(root_quads3, arraysize(root_quads3), root_pass_ids[2])};
+
+    cc::RenderPassList root_pass_list;
+    AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+              arraysize(root_passes));
+
+    auto* filter_pass = root_pass_list[1].get();
+    filter_pass->shared_quad_state_list.front()
+        ->quad_to_target_transform.Translate(10, 10);
+    auto* root_pass = root_pass_list[2].get();
+    filter_pass->filters.Append(cc::FilterOperation::CreateBlurFilter(2));
+    root_pass->damage_rect = gfx::Rect(10, 10, 2, 2);
+    SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
+                          &root_pass_list);
+  }
+
+  {
+    cc::CompositorFrame aggregated_frame =
+        aggregator_.Aggregate(root_surface_id);
+
+    const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+    ASSERT_EQ(4u, aggregated_pass_list.size());
+
+    EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[0]->damage_rect);
+    EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[1]->damage_rect);
+    EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[2]->damage_rect);
+    EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[3]->damage_rect);
+    EXPECT_EQ(1u, aggregated_pass_list[0]->quad_list.size());
+    EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size());
+    EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size());
+    // First render pass draw quad is outside damage rect, so shouldn't be
+    // drawn.
+    EXPECT_EQ(0u, aggregated_pass_list[3]->quad_list.size());
+  }
+
+  // Root surface has smaller damage rect. Background filter on render pass
+  // means Surface
+  // quad under it should be aggregated.
+  {
+    int root_pass_ids[] = {1, 2};
+    Quad root_quads1[] = {
+        Quad::SolidColorQuad(1),
+    };
+    Quad root_quads2[] = {
+        Quad::RenderPassQuad(root_pass_ids[0]),
+        Quad::SurfaceQuad(child_surface_id, InvalidSurfaceId(), 1.f)};
+    Pass root_passes[] = {
+        Pass(root_quads1, arraysize(root_quads1), root_pass_ids[0]),
+        Pass(root_quads2, arraysize(root_quads2), root_pass_ids[1])};
+
+    cc::RenderPassList root_pass_list;
+    AddPasses(&root_pass_list, gfx::Rect(SurfaceSize()), root_passes,
+              arraysize(root_passes));
+
+    auto* pass = root_pass_list[0].get();
+    auto* root_pass = root_pass_list[1].get();
+    root_pass->shared_quad_state_list.ElementAt(1)
+        ->quad_to_target_transform.Translate(10, 10);
+    pass->background_filters.Append(cc::FilterOperation::CreateBlurFilter(2));
+    root_pass->damage_rect = gfx::Rect(10, 10, 2, 2);
+    SubmitPassListAsFrame(support_.get(), root_local_surface_id_,
+                          &root_pass_list);
+  }
+
+  {
+    cc::CompositorFrame aggregated_frame =
+        aggregator_.Aggregate(root_surface_id);
+
+    const auto& aggregated_pass_list = aggregated_frame.render_pass_list;
+
+    ASSERT_EQ(3u, aggregated_pass_list.size());
+
+    // Pass 0 is solid color quad from root, but outside damage rect.
+    EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[0]->damage_rect);
+    EXPECT_EQ(0u, aggregated_pass_list[0]->quad_list.size());
+    EXPECT_EQ(gfx::Rect(SurfaceSize()), aggregated_pass_list[1]->damage_rect);
+    EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size());
+
+    // First render pass draw quad is outside damage rect, so shouldn't be
+    // drawn. SurfaceDrawQuad is after background filter, so corresponding
+    // RenderPassDrawQuad should be drawn.
+    EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[2]->damage_rect);
+    EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size());
+  }
+}
+
+class SurfaceAggregatorWithResourcesTest : public testing::Test {
+ public:
+  void SetUp() override {
+    shared_bitmap_manager_ = base::MakeUnique<cc::TestSharedBitmapManager>();
+    resource_provider_ =
+        cc::FakeResourceProvider::Create(nullptr, shared_bitmap_manager_.get());
+
+    aggregator_ = base::MakeUnique<SurfaceAggregator>(
+        manager_.surface_manager(), resource_provider_.get(), false);
+    aggregator_->set_output_is_secure(true);
+  }
+
+ protected:
+  cc::FrameSinkManager manager_;
+  std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_;
+  std::unique_ptr<cc::ResourceProvider> resource_provider_;
+  std::unique_ptr<SurfaceAggregator> aggregator_;
+};
+
+void SubmitCompositorFrameWithResources(cc::ResourceId* resource_ids,
+                                        size_t num_resource_ids,
+                                        bool valid,
+                                        SurfaceId child_id,
+                                        CompositorFrameSinkSupport* support,
+                                        SurfaceId surface_id) {
+  cc::CompositorFrame frame = cc::test::MakeEmptyCompositorFrame();
+  auto pass = cc::RenderPass::Create();
+  pass->SetNew(1, gfx::Rect(0, 0, 20, 20), gfx::Rect(), gfx::Transform());
+  auto* sqs = pass->CreateAndAppendSharedQuadState();
+  sqs->opacity = 1.f;
+  if (child_id.is_valid()) {
+    auto* surface_quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
+    surface_quad->SetNew(sqs, gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1),
+                         child_id, cc::SurfaceDrawQuadType::PRIMARY, nullptr);
+  }
+
+  for (size_t i = 0u; i < num_resource_ids; ++i) {
+    cc::TransferableResource resource;
+    resource.id = resource_ids[i];
+    // ResourceProvider is software, so only software resources are valid.
+    resource.is_software = valid;
+    frame.resource_list.push_back(resource);
+    auto* quad = pass->CreateAndAppendDrawQuad<cc::TextureDrawQuad>();
+    const gfx::Rect rect;
+    const gfx::Rect opaque_rect;
+    const gfx::Rect visible_rect;
+    bool needs_blending = false;
+    bool premultiplied_alpha = false;
+    const gfx::PointF uv_top_left;
+    const gfx::PointF uv_bottom_right;
+    SkColor background_color = SK_ColorGREEN;
+    const float vertex_opacity[4] = {0.f, 0.f, 1.f, 1.f};
+    bool flipped = false;
+    bool nearest_neighbor = false;
+    bool secure_output_only = true;
+    quad->SetAll(sqs, rect, opaque_rect, visible_rect, needs_blending,
+                 resource_ids[i], gfx::Size(), premultiplied_alpha, uv_top_left,
+                 uv_bottom_right, background_color, vertex_opacity, flipped,
+                 nearest_neighbor, secure_output_only);
+  }
+  frame.render_pass_list.push_back(std::move(pass));
+  support->SubmitCompositorFrame(surface_id.local_surface_id(),
+                                 std::move(frame));
+}
+
+TEST_F(SurfaceAggregatorWithResourcesTest, TakeResourcesOneSurface) {
+  cc::FakeCompositorFrameSinkSupportClient client;
+  auto support = CompositorFrameSinkSupport::Create(
+      &client, &manager_, kArbitraryRootFrameSinkId, kRootIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId local_surface_id(7u, base::UnguessableToken::Create());
+  SurfaceId surface_id(support->frame_sink_id(), local_surface_id);
+
+  cc::ResourceId ids[] = {11, 12, 13};
+  SubmitCompositorFrameWithResources(ids, arraysize(ids), true, SurfaceId(),
+                                     support.get(), surface_id);
+
+  cc::CompositorFrame frame = aggregator_->Aggregate(surface_id);
+
+  // Nothing should be available to be returned yet.
+  EXPECT_TRUE(client.returned_resources().empty());
+
+  SubmitCompositorFrameWithResources(NULL, 0u, true, SurfaceId(), support.get(),
+                                     surface_id);
+
+  frame = aggregator_->Aggregate(surface_id);
+
+  ASSERT_EQ(3u, client.returned_resources().size());
+  cc::ResourceId returned_ids[3];
+  for (size_t i = 0; i < 3; ++i) {
+    returned_ids[i] = client.returned_resources()[i].id;
+  }
+  EXPECT_THAT(returned_ids,
+              testing::WhenSorted(testing::ElementsAreArray(ids)));
+
+  support->EvictCurrentSurface();
+}
+
+// This test verifies that when a CompositorFrame is submitted to a new surface
+// ID, and a new display frame is generated, then the resources of the old
+// surface are returned to the appropriate client.
+TEST_F(SurfaceAggregatorWithResourcesTest, ReturnResourcesAsSurfacesChange) {
+  cc::FakeCompositorFrameSinkSupportClient client;
+  auto support = CompositorFrameSinkSupport::Create(
+      &client, &manager_, kArbitraryRootFrameSinkId, kRootIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId local_surface_id1(7u, base::UnguessableToken::Create());
+  LocalSurfaceId local_surface_id2(8u, base::UnguessableToken::Create());
+  SurfaceId surface_id1(support->frame_sink_id(), local_surface_id1);
+  SurfaceId surface_id2(support->frame_sink_id(), local_surface_id2);
+
+  cc::ResourceId ids[] = {11, 12, 13};
+  SubmitCompositorFrameWithResources(ids, arraysize(ids), true, SurfaceId(),
+                                     support.get(), surface_id1);
+
+  cc::CompositorFrame frame = aggregator_->Aggregate(surface_id1);
+
+  // Nothing should be available to be returned yet.
+  EXPECT_TRUE(client.returned_resources().empty());
+
+  // Submitting a CompositorFrame to |surface_id2| should cause the surface
+  // associated with |surface_id1| to get garbage collected.
+  SubmitCompositorFrameWithResources(NULL, 0u, true, SurfaceId(), support.get(),
+                                     surface_id2);
+
+  frame = aggregator_->Aggregate(surface_id2);
+
+  ASSERT_EQ(3u, client.returned_resources().size());
+  cc::ResourceId returned_ids[3];
+  for (size_t i = 0; i < 3; ++i) {
+    returned_ids[i] = client.returned_resources()[i].id;
+  }
+  EXPECT_THAT(returned_ids,
+              testing::WhenSorted(testing::ElementsAreArray(ids)));
+
+  support->EvictCurrentSurface();
+}
+
+TEST_F(SurfaceAggregatorWithResourcesTest, TakeInvalidResources) {
+  cc::FakeCompositorFrameSinkSupportClient client;
+  auto support = CompositorFrameSinkSupport::Create(
+      &client, &manager_, kArbitraryRootFrameSinkId, kRootIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId local_surface_id(7u, base::UnguessableToken::Create());
+  SurfaceId surface_id(support->frame_sink_id(), local_surface_id);
+
+  cc::CompositorFrame frame = cc::test::MakeCompositorFrame();
+  cc::TransferableResource resource;
+  resource.id = 11;
+  // ResourceProvider is software but resource is not, so it should be
+  // ignored.
+  resource.is_software = false;
+  frame.resource_list.push_back(resource);
+  support->SubmitCompositorFrame(local_surface_id, std::move(frame));
+
+  cc::CompositorFrame returned_frame = aggregator_->Aggregate(surface_id);
+
+  // Nothing should be available to be returned yet.
+  EXPECT_TRUE(client.returned_resources().empty());
+
+  SubmitCompositorFrameWithResources(NULL, 0, true, SurfaceId(), support.get(),
+                                     surface_id);
+  ASSERT_EQ(1u, client.returned_resources().size());
+  EXPECT_EQ(11u, client.returned_resources()[0].id);
+
+  support->EvictCurrentSurface();
+}
+
+TEST_F(SurfaceAggregatorWithResourcesTest, TwoSurfaces) {
+  cc::FakeCompositorFrameSinkSupportClient client;
+  auto support1 = CompositorFrameSinkSupport::Create(
+      &client, &manager_, FrameSinkId(1, 1), kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto support2 = CompositorFrameSinkSupport::Create(
+      &client, &manager_, FrameSinkId(2, 2), kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId local_frame1_id(7u, base::UnguessableToken::Create());
+  SurfaceId surface1_id(support1->frame_sink_id(), local_frame1_id);
+
+  LocalSurfaceId local_frame2_id(8u, base::UnguessableToken::Create());
+  SurfaceId surface2_id(support2->frame_sink_id(), local_frame2_id);
+
+  cc::ResourceId ids[] = {11, 12, 13};
+  SubmitCompositorFrameWithResources(ids, arraysize(ids), true, SurfaceId(),
+                                     support1.get(), surface1_id);
+  cc::ResourceId ids2[] = {14, 15, 16};
+  SubmitCompositorFrameWithResources(ids2, arraysize(ids2), true, SurfaceId(),
+                                     support2.get(), surface2_id);
+
+  cc::CompositorFrame frame = aggregator_->Aggregate(surface1_id);
+
+  SubmitCompositorFrameWithResources(NULL, 0, true, SurfaceId(), support1.get(),
+                                     surface1_id);
+
+  // Nothing should be available to be returned yet.
+  EXPECT_TRUE(client.returned_resources().empty());
+
+  frame = aggregator_->Aggregate(surface2_id);
+
+  // surface1_id wasn't referenced, so its resources should be returned.
+  ASSERT_EQ(3u, client.returned_resources().size());
+  cc::ResourceId returned_ids[3];
+  for (size_t i = 0; i < 3; ++i) {
+    returned_ids[i] = client.returned_resources()[i].id;
+  }
+  EXPECT_THAT(returned_ids,
+              testing::WhenSorted(testing::ElementsAreArray(ids)));
+  EXPECT_EQ(3u, resource_provider_->num_resources());
+
+  support1->EvictCurrentSurface();
+  support2->EvictCurrentSurface();
+}
+
+// Ensure that aggregator completely ignores Surfaces that reference invalid
+// resources.
+TEST_F(SurfaceAggregatorWithResourcesTest, InvalidChildSurface) {
+  auto root_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryRootFrameSinkId, kRootIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto middle_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryMiddleFrameSinkId, kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto child_support = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, kArbitraryFrameSinkId1, kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId root_local_surface_id(7u, kArbitraryToken);
+  SurfaceId root_surface_id(root_support->frame_sink_id(),
+                            root_local_surface_id);
+  LocalSurfaceId middle_local_surface_id(8u, kArbitraryToken);
+  SurfaceId middle_surface_id(middle_support->frame_sink_id(),
+                              middle_local_surface_id);
+  LocalSurfaceId child_local_surface_id(9u, kArbitraryToken);
+  SurfaceId child_surface_id(child_support->frame_sink_id(),
+                             child_local_surface_id);
+
+  cc::ResourceId ids[] = {14, 15, 16};
+  SubmitCompositorFrameWithResources(ids, arraysize(ids), true, SurfaceId(),
+                                     child_support.get(), child_surface_id);
+
+  cc::ResourceId ids2[] = {17, 18, 19};
+  SubmitCompositorFrameWithResources(ids2, arraysize(ids2), false,
+                                     child_surface_id, middle_support.get(),
+                                     middle_surface_id);
+
+  cc::ResourceId ids3[] = {20, 21, 22};
+  SubmitCompositorFrameWithResources(ids3, arraysize(ids3), true,
+                                     middle_surface_id, root_support.get(),
+                                     root_surface_id);
+
+  cc::CompositorFrame frame;
+  frame = aggregator_->Aggregate(root_surface_id);
+
+  auto* pass_list = &frame.render_pass_list;
+  ASSERT_EQ(1u, pass_list->size());
+  EXPECT_EQ(1u, pass_list->back()->shared_quad_state_list.size());
+  EXPECT_EQ(3u, pass_list->back()->quad_list.size());
+  SubmitCompositorFrameWithResources(ids2, arraysize(ids), true,
+                                     child_surface_id, middle_support.get(),
+                                     middle_surface_id);
+
+  frame = aggregator_->Aggregate(root_surface_id);
+
+  pass_list = &frame.render_pass_list;
+  ASSERT_EQ(1u, pass_list->size());
+  EXPECT_EQ(3u, pass_list->back()->shared_quad_state_list.size());
+  EXPECT_EQ(9u, pass_list->back()->quad_list.size());
+
+  root_support->EvictCurrentSurface();
+  middle_support->EvictCurrentSurface();
+  child_support->EvictCurrentSurface();
+}
+
+TEST_F(SurfaceAggregatorWithResourcesTest, SecureOutputTexture) {
+  auto support1 = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, FrameSinkId(1, 1), kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  auto support2 = CompositorFrameSinkSupport::Create(
+      nullptr, &manager_, FrameSinkId(2, 2), kChildIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId local_frame1_id(7u, base::UnguessableToken::Create());
+  SurfaceId surface1_id(support1->frame_sink_id(), local_frame1_id);
+
+  LocalSurfaceId local_frame2_id(8u, base::UnguessableToken::Create());
+  SurfaceId surface2_id(support2->frame_sink_id(), local_frame2_id);
+
+  cc::ResourceId ids[] = {11, 12, 13};
+  SubmitCompositorFrameWithResources(ids, arraysize(ids), true, SurfaceId(),
+                                     support1.get(), surface1_id);
+
+  cc::CompositorFrame frame = aggregator_->Aggregate(surface1_id);
+
+  auto* render_pass = frame.render_pass_list.back().get();
+
+  EXPECT_EQ(cc::DrawQuad::TEXTURE_CONTENT,
+            render_pass->quad_list.back()->material);
+
+  {
+    auto pass = cc::RenderPass::Create();
+    pass->SetNew(1, gfx::Rect(0, 0, 20, 20), gfx::Rect(), gfx::Transform());
+    auto* sqs = pass->CreateAndAppendSharedQuadState();
+    sqs->opacity = 1.f;
+    auto* surface_quad = pass->CreateAndAppendDrawQuad<cc::SurfaceDrawQuad>();
+
+    surface_quad->SetNew(sqs, gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1),
+                         surface1_id, cc::SurfaceDrawQuadType::PRIMARY,
+                         nullptr);
+    pass->copy_requests.push_back(cc::CopyOutputRequest::CreateEmptyRequest());
+
+    cc::CompositorFrame frame = cc::test::MakeEmptyCompositorFrame();
+    frame.render_pass_list.push_back(std::move(pass));
+
+    support2->SubmitCompositorFrame(local_frame2_id, std::move(frame));
+  }
+
+  frame = aggregator_->Aggregate(surface2_id);
+  EXPECT_EQ(1u, frame.render_pass_list.size());
+  render_pass = frame.render_pass_list.front().get();
+
+  // Parent has copy request, so texture should not be drawn.
+  EXPECT_EQ(cc::DrawQuad::SOLID_COLOR, render_pass->quad_list.back()->material);
+
+  frame = aggregator_->Aggregate(surface2_id);
+  EXPECT_EQ(1u, frame.render_pass_list.size());
+  render_pass = frame.render_pass_list.front().get();
+
+  // Copy request has been executed earlier, so texture should be drawn.
+  EXPECT_EQ(cc::DrawQuad::TEXTURE_CONTENT,
+            render_pass->quad_list.front()->material);
+
+  aggregator_->set_output_is_secure(false);
+
+  frame = aggregator_->Aggregate(surface2_id);
+  render_pass = frame.render_pass_list.back().get();
+
+  // Output is insecure, so texture should be drawn.
+  EXPECT_EQ(cc::DrawQuad::SOLID_COLOR, render_pass->quad_list.back()->material);
+
+  support1->EvictCurrentSurface();
+  support2->EvictCurrentSurface();
+}
+
+// Ensure that the render passes have correct color spaces.
+TEST_F(SurfaceAggregatorValidSurfaceTest, ColorSpaceTest) {
+  Quad quads[][2] = {{Quad::SolidColorQuad(SK_ColorWHITE),
+                      Quad::SolidColorQuad(SK_ColorLTGRAY)},
+                     {Quad::SolidColorQuad(SK_ColorGRAY),
+                      Quad::SolidColorQuad(SK_ColorDKGRAY)}};
+  Pass passes[] = {Pass(quads[0], arraysize(quads[0]), 2),
+                   Pass(quads[1], arraysize(quads[1]), 1)};
+  gfx::ColorSpace color_space1 = gfx::ColorSpace::CreateXYZD50();
+  gfx::ColorSpace color_space2 = gfx::ColorSpace::CreateSRGB();
+  gfx::ColorSpace color_space3 = gfx::ColorSpace::CreateSCRGBLinear();
+
+  SubmitCompositorFrame(support_.get(), passes, arraysize(passes),
+                        root_local_surface_id_);
+
+  SurfaceId surface_id(support_->frame_sink_id(), root_local_surface_id_);
+
+  cc::CompositorFrame aggregated_frame;
+  aggregator_.SetOutputColorSpace(color_space1, color_space1);
+  aggregated_frame = aggregator_.Aggregate(surface_id);
+  EXPECT_EQ(2u, aggregated_frame.render_pass_list.size());
+  EXPECT_EQ(color_space1, aggregated_frame.render_pass_list[0]->color_space);
+  EXPECT_EQ(color_space1, aggregated_frame.render_pass_list[1]->color_space);
+
+  aggregator_.SetOutputColorSpace(color_space2, color_space2);
+  aggregated_frame = aggregator_.Aggregate(surface_id);
+  EXPECT_EQ(2u, aggregated_frame.render_pass_list.size());
+  EXPECT_EQ(color_space2, aggregated_frame.render_pass_list[0]->color_space);
+  EXPECT_EQ(color_space2, aggregated_frame.render_pass_list[1]->color_space);
+
+  aggregator_.SetOutputColorSpace(color_space1, color_space3);
+  aggregated_frame = aggregator_.Aggregate(surface_id);
+  EXPECT_EQ(3u, aggregated_frame.render_pass_list.size());
+  EXPECT_EQ(color_space1, aggregated_frame.render_pass_list[0]->color_space);
+  EXPECT_EQ(color_space1, aggregated_frame.render_pass_list[1]->color_space);
+  EXPECT_EQ(color_space3, aggregated_frame.render_pass_list[2]->color_space);
+}
+
+}  // namespace
+}  // namespace viz
diff --git a/components/viz/service/display_embedder/display_provider.h b/components/viz/service/display_embedder/display_provider.h
index 37ba0a26..a6cba01d 100644
--- a/components/viz/service/display_embedder/display_provider.h
+++ b/components/viz/service/display_embedder/display_provider.h
@@ -11,21 +11,20 @@
 
 namespace cc {
 class BeginFrameSource;
-class Display;
 class FrameSinkId;
 }  // namespace cc
 
 namespace viz {
+class Display;
 
-// Handles creating new cc::Displays and related classes for
-// FrameSinkManagerImpl.
+// Handles creating Display and related classes for FrameSinkManagerImpl.
 class DisplayProvider {
  public:
   virtual ~DisplayProvider() {}
 
-  // Creates a new cc::Display for |surface_handle| with |frame_sink_id|. Will
+  // Creates a new Display for |surface_handle| with |frame_sink_id|. Will
   // also create cc::BeginFrameSource and return it in |begin_frame_source|.
-  virtual std::unique_ptr<cc::Display> CreateDisplay(
+  virtual std::unique_ptr<Display> CreateDisplay(
       const FrameSinkId& frame_sink_id,
       gpu::SurfaceHandle surface_handle,
       std::unique_ptr<cc::BeginFrameSource>* begin_frame_source) = 0;
diff --git a/components/viz/service/display_embedder/gpu_display_provider.cc b/components/viz/service/display_embedder/gpu_display_provider.cc
index d1fd741..0891a9f 100644
--- a/components/viz/service/display_embedder/gpu_display_provider.cc
+++ b/components/viz/service/display_embedder/gpu_display_provider.cc
@@ -13,8 +13,8 @@
 #include "cc/output/in_process_context_provider.h"
 #include "cc/output/texture_mailbox_deleter.h"
 #include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/display.h"
-#include "cc/surfaces/display_scheduler.h"
+#include "components/viz/service/display/display.h"
+#include "components/viz/service/display/display_scheduler.h"
 #include "components/viz/service/display_embedder/display_output_surface.h"
 #include "components/viz/service/display_embedder/in_process_gpu_memory_buffer_manager.h"
 #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
@@ -51,7 +51,7 @@
 
 GpuDisplayProvider::~GpuDisplayProvider() = default;
 
-std::unique_ptr<cc::Display> GpuDisplayProvider::CreateDisplay(
+std::unique_ptr<Display> GpuDisplayProvider::CreateDisplay(
     const FrameSinkId& frame_sink_id,
     gpu::SurfaceHandle surface_handle,
     std::unique_ptr<cc::BeginFrameSource>* begin_frame_source) {
@@ -87,7 +87,7 @@
       display_output_surface->capabilities().max_frames_pending;
   DCHECK_GT(max_frames_pending, 0);
 
-  auto scheduler = base::MakeUnique<cc::DisplayScheduler>(
+  auto scheduler = base::MakeUnique<DisplayScheduler>(
       synthetic_begin_frame_source.get(), task_runner_.get(),
       max_frames_pending);
 
@@ -99,7 +99,7 @@
   // The ownership of the BeginFrameSource is transfered to the caller.
   *begin_frame_source = std::move(synthetic_begin_frame_source);
 
-  return base::MakeUnique<cc::Display>(
+  return base::MakeUnique<Display>(
       ServerSharedBitmapManager::current(), gpu_memory_buffer_manager_.get(),
       settings, frame_sink_id, std::move(display_output_surface),
       std::move(scheduler),
diff --git a/components/viz/service/display_embedder/gpu_display_provider.h b/components/viz/service/display_embedder/gpu_display_provider.h
index fb37618d..6932e2e0 100644
--- a/components/viz/service/display_embedder/gpu_display_provider.h
+++ b/components/viz/service/display_embedder/gpu_display_provider.h
@@ -23,6 +23,7 @@
 }  // namespace gpu
 
 namespace viz {
+class Display;
 
 // In-process implementation of DisplayProvider.
 class VIZ_SERVICE_EXPORT GpuDisplayProvider
@@ -34,7 +35,7 @@
   ~GpuDisplayProvider() override;
 
   // DisplayProvider:
-  std::unique_ptr<cc::Display> CreateDisplay(
+  std::unique_ptr<Display> CreateDisplay(
       const FrameSinkId& frame_sink_id,
       gpu::SurfaceHandle surface_handle,
       std::unique_ptr<cc::BeginFrameSource>* begin_frame_source) override;
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
new file mode 100644
index 0000000..612a50b
--- /dev/null
+++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.cc
@@ -0,0 +1,374 @@
+// 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 "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
+
+#include <algorithm>
+#include <utility>
+
+#include "cc/output/compositor_frame.h"
+#include "cc/scheduler/begin_frame_source.h"
+#include "cc/surfaces/frame_sink_manager.h"
+#include "cc/surfaces/surface.h"
+#include "cc/surfaces/surface_info.h"
+#include "cc/surfaces/surface_reference.h"
+#include "components/viz/service/display/display.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h"
+
+namespace viz {
+
+// static
+std::unique_ptr<CompositorFrameSinkSupport> CompositorFrameSinkSupport::Create(
+    CompositorFrameSinkSupportClient* client,
+    cc::FrameSinkManager* frame_sink_manager,
+    const FrameSinkId& frame_sink_id,
+    bool is_root,
+    bool handles_frame_sink_id_invalidation,
+    bool needs_sync_tokens) {
+  std::unique_ptr<CompositorFrameSinkSupport> support =
+      base::WrapUnique(new CompositorFrameSinkSupport(
+          client, frame_sink_id, is_root, handles_frame_sink_id_invalidation,
+          needs_sync_tokens));
+  support->Init(frame_sink_manager);
+  return support;
+}
+
+CompositorFrameSinkSupport::~CompositorFrameSinkSupport() {
+  // Unregister |this| as a cc::BeginFrameObserver so that the
+  // cc::BeginFrameSource does not call into |this| after it's deleted.
+  SetNeedsBeginFrame(false);
+
+  // For display root surfaces the surface is no longer going to be visible.
+  // Make it unreachable from the top-level root.
+  if (referenced_local_surface_id_.has_value()) {
+    auto reference = MakeTopLevelRootReference(
+        SurfaceId(frame_sink_id_, referenced_local_surface_id_.value()));
+    surface_manager_->RemoveSurfaceReferences({reference});
+  }
+
+  EvictCurrentSurface();
+  frame_sink_manager_->UnregisterFrameSinkManagerClient(frame_sink_id_);
+  if (handles_frame_sink_id_invalidation_)
+    frame_sink_manager_->InvalidateFrameSinkId(frame_sink_id_);
+}
+
+void CompositorFrameSinkSupport::OnSurfaceActivated(cc::Surface* surface) {
+  DCHECK(surface->HasActiveFrame());
+  const cc::CompositorFrame& frame = surface->GetActiveFrame();
+  if (!seen_first_frame_activation_) {
+    // cc::SurfaceCreated only applies for the first cc::Surface activation.
+    seen_first_frame_activation_ = true;
+
+    gfx::Size frame_size = frame.render_pass_list.back()->output_rect.size();
+    surface_manager_->SurfaceCreated(cc::SurfaceInfo(
+        surface->surface_id(), frame.metadata.device_scale_factor, frame_size));
+  }
+  // Fire cc::SurfaceCreated first so that a temporary reference is added before
+  // it is potentially transformed into a real reference by the client.
+  DCHECK(surface->active_referenced_surfaces());
+  UpdateSurfaceReferences(surface->surface_id().local_surface_id(),
+                          *surface->active_referenced_surfaces());
+  if (!surface_manager_->SurfaceModified(surface->surface_id(),
+                                         frame.metadata.begin_frame_ack)) {
+    TRACE_EVENT_INSTANT0("cc", "Damage not visible.", TRACE_EVENT_SCOPE_THREAD);
+    surface->RunDrawCallback();
+  }
+  surface_manager_->SurfaceActivated(surface);
+}
+
+void CompositorFrameSinkSupport::RefResources(
+    const std::vector<cc::TransferableResource>& resources) {
+  surface_resource_holder_.RefResources(resources);
+}
+
+void CompositorFrameSinkSupport::UnrefResources(
+    const std::vector<cc::ReturnedResource>& resources) {
+  surface_resource_holder_.UnrefResources(resources);
+}
+
+void CompositorFrameSinkSupport::ReturnResources(
+    const std::vector<cc::ReturnedResource>& resources) {
+  if (resources.empty())
+    return;
+  if (!ack_pending_count_ && client_) {
+    client_->ReclaimResources(resources);
+    return;
+  }
+
+  std::copy(resources.begin(), resources.end(),
+            std::back_inserter(surface_returned_resources_));
+}
+
+void CompositorFrameSinkSupport::ReceiveFromChild(
+    const std::vector<cc::TransferableResource>& resources) {
+  surface_resource_holder_.ReceiveFromChild(resources);
+}
+
+void CompositorFrameSinkSupport::SetBeginFrameSource(
+    cc::BeginFrameSource* begin_frame_source) {
+  if (begin_frame_source_ && added_frame_observer_) {
+    begin_frame_source_->RemoveObserver(this);
+    added_frame_observer_ = false;
+  }
+  begin_frame_source_ = begin_frame_source;
+  UpdateNeedsBeginFramesInternal();
+}
+
+void CompositorFrameSinkSupport::EvictCurrentSurface() {
+  if (!current_surface_id_.is_valid())
+    return;
+  SurfaceId to_destroy_surface_id = current_surface_id_;
+  current_surface_id_ = SurfaceId();
+  surface_manager_->DestroySurface(to_destroy_surface_id);
+}
+
+void CompositorFrameSinkSupport::SetNeedsBeginFrame(bool needs_begin_frame) {
+  needs_begin_frame_ = needs_begin_frame;
+  UpdateNeedsBeginFramesInternal();
+}
+
+void CompositorFrameSinkSupport::DidNotProduceFrame(
+    const cc::BeginFrameAck& ack) {
+  TRACE_EVENT2("cc", "CompositorFrameSinkSupport::DidNotProduceFrame",
+               "ack.source_id", ack.source_id, "ack.sequence_number",
+               ack.sequence_number);
+  DCHECK_GE(ack.sequence_number, cc::BeginFrameArgs::kStartingFrameNumber);
+
+  // |has_damage| is not transmitted, but false by default.
+  DCHECK(!ack.has_damage);
+
+  if (current_surface_id_.is_valid())
+    surface_manager_->SurfaceModified(current_surface_id_, ack);
+
+  if (begin_frame_source_)
+    begin_frame_source_->DidFinishFrame(this);
+}
+
+bool CompositorFrameSinkSupport::SubmitCompositorFrame(
+    const LocalSurfaceId& local_surface_id,
+    cc::CompositorFrame frame) {
+  TRACE_EVENT0("cc", "CompositorFrameSinkSupport::SubmitCompositorFrame");
+  DCHECK(local_surface_id.is_valid());
+  DCHECK(!frame.render_pass_list.empty());
+
+  ++ack_pending_count_;
+
+  // |has_damage| is not transmitted.
+  frame.metadata.begin_frame_ack.has_damage = true;
+  cc::BeginFrameAck ack = frame.metadata.begin_frame_ack;
+  DCHECK_LE(cc::BeginFrameArgs::kStartingFrameNumber, ack.sequence_number);
+
+  if (!ui::LatencyInfo::Verify(frame.metadata.latency_info,
+                               "RenderWidgetHostImpl::OnSwapCompositorFrame")) {
+    std::vector<ui::LatencyInfo>().swap(frame.metadata.latency_info);
+  }
+  for (ui::LatencyInfo& latency : frame.metadata.latency_info) {
+    if (latency.latency_components().size() > 0) {
+      latency.AddLatencyNumber(ui::DISPLAY_COMPOSITOR_RECEIVED_FRAME_COMPONENT,
+                               0, 0);
+    }
+  }
+
+  cc::Surface* prev_surface =
+      surface_manager_->GetSurfaceForId(current_surface_id_);
+  cc::Surface* current_surface = nullptr;
+  if (prev_surface &&
+      local_surface_id == current_surface_id_.local_surface_id()) {
+    current_surface = prev_surface;
+  } else {
+    SurfaceId surface_id(frame_sink_id_, local_surface_id);
+    gfx::Size frame_size = frame.render_pass_list.back()->output_rect.size();
+    float device_scale_factor = frame.metadata.device_scale_factor;
+    cc::SurfaceInfo surface_info(surface_id, device_scale_factor, frame_size);
+
+    if (!surface_info.is_valid()) {
+      TRACE_EVENT_INSTANT0("cc", "Invalid cc::SurfaceInfo",
+                           TRACE_EVENT_SCOPE_THREAD);
+      EvictCurrentSurface();
+      std::vector<cc::ReturnedResource> resources =
+          cc::TransferableResource::ReturnResources(frame.resource_list);
+      ReturnResources(resources);
+      DidReceiveCompositorFrameAck();
+      return true;
+    }
+
+    current_surface = CreateSurface(surface_info);
+    current_surface_id_ = SurfaceId(frame_sink_id_, local_surface_id);
+    surface_manager_->SurfaceDamageExpected(current_surface->surface_id(),
+                                            last_begin_frame_args_);
+  }
+
+  bool result = current_surface->QueueFrame(
+      std::move(frame),
+      base::Bind(&CompositorFrameSinkSupport::DidReceiveCompositorFrameAck,
+                 weak_factory_.GetWeakPtr()),
+      base::BindRepeating(&CompositorFrameSinkSupport::WillDrawSurface,
+                          weak_factory_.GetWeakPtr()));
+
+  if (!result) {
+    EvictCurrentSurface();
+    return false;
+  }
+
+  if (prev_surface && prev_surface != current_surface) {
+    current_surface->SetPreviousFrameSurface(prev_surface);
+    surface_manager_->DestroySurface(prev_surface->surface_id());
+  }
+
+  if (begin_frame_source_)
+    begin_frame_source_->DidFinishFrame(this);
+
+  return true;
+}
+
+void CompositorFrameSinkSupport::UpdateSurfaceReferences(
+    const LocalSurfaceId& local_surface_id,
+    const std::vector<SurfaceId>& active_referenced_surfaces) {
+  SurfaceId surface_id(frame_sink_id_, local_surface_id);
+
+  const base::flat_set<SurfaceId>& existing_referenced_surfaces =
+      surface_manager_->GetSurfacesReferencedByParent(surface_id);
+
+  base::flat_set<SurfaceId> new_referenced_surfaces(
+      active_referenced_surfaces.begin(), active_referenced_surfaces.end(),
+      base::KEEP_FIRST_OF_DUPES);
+
+  // Populate list of surface references to add and remove by getting the
+  // difference between existing surface references and surface references for
+  // latest activated CompositorFrame.
+  std::vector<cc::SurfaceReference> references_to_add;
+  std::vector<cc::SurfaceReference> references_to_remove;
+  GetSurfaceReferenceDifference(surface_id, existing_referenced_surfaces,
+                                new_referenced_surfaces, &references_to_add,
+                                &references_to_remove);
+
+  // Check if this is a display root surface and the SurfaceId is changing.
+  if (is_root_ && (!referenced_local_surface_id_.has_value() ||
+                   referenced_local_surface_id_.value() != local_surface_id)) {
+    // Make the new SurfaceId reachable from the top-level root.
+    references_to_add.push_back(MakeTopLevelRootReference(surface_id));
+
+    // Make the old SurfaceId unreachable from the top-level root if applicable.
+    if (referenced_local_surface_id_.has_value()) {
+      references_to_remove.push_back(MakeTopLevelRootReference(
+          SurfaceId(frame_sink_id_, referenced_local_surface_id_.value())));
+    }
+
+    referenced_local_surface_id_ = local_surface_id;
+  }
+
+  // Modify surface references stored in cc::SurfaceManager.
+  if (!references_to_add.empty())
+    surface_manager_->AddSurfaceReferences(references_to_add);
+  if (!references_to_remove.empty())
+    surface_manager_->RemoveSurfaceReferences(references_to_remove);
+}
+
+cc::SurfaceReference CompositorFrameSinkSupport::MakeTopLevelRootReference(
+    const SurfaceId& surface_id) {
+  return cc::SurfaceReference(surface_manager_->GetRootSurfaceId(), surface_id);
+}
+
+void CompositorFrameSinkSupport::DidReceiveCompositorFrameAck() {
+  DCHECK_GT(ack_pending_count_, 0);
+  ack_pending_count_--;
+  if (!client_)
+    return;
+
+  client_->DidReceiveCompositorFrameAck(surface_returned_resources_);
+  surface_returned_resources_.clear();
+}
+
+void CompositorFrameSinkSupport::WillDrawSurface(
+    const LocalSurfaceId& local_surface_id,
+    const gfx::Rect& damage_rect) {
+  if (client_)
+    client_->WillDrawSurface(local_surface_id, damage_rect);
+}
+
+void CompositorFrameSinkSupport::ClaimTemporaryReference(
+    const SurfaceId& surface_id) {
+  surface_manager_->AssignTemporaryReference(surface_id, frame_sink_id_);
+}
+
+CompositorFrameSinkSupport::CompositorFrameSinkSupport(
+    CompositorFrameSinkSupportClient* client,
+    const FrameSinkId& frame_sink_id,
+    bool is_root,
+    bool handles_frame_sink_id_invalidation,
+    bool needs_sync_tokens)
+    : client_(client),
+      frame_sink_id_(frame_sink_id),
+      surface_resource_holder_(this),
+      is_root_(is_root),
+      needs_sync_tokens_(needs_sync_tokens),
+      handles_frame_sink_id_invalidation_(handles_frame_sink_id_invalidation),
+      weak_factory_(this) {}
+
+void CompositorFrameSinkSupport::Init(
+    cc::FrameSinkManager* frame_sink_manager) {
+  frame_sink_manager_ = frame_sink_manager;
+  surface_manager_ = frame_sink_manager->surface_manager();
+  if (handles_frame_sink_id_invalidation_)
+    frame_sink_manager_->RegisterFrameSinkId(frame_sink_id_);
+  frame_sink_manager_->RegisterFrameSinkManagerClient(frame_sink_id_, this);
+}
+
+void CompositorFrameSinkSupport::OnBeginFrame(const cc::BeginFrameArgs& args) {
+  UpdateNeedsBeginFramesInternal();
+  if (current_surface_id_.is_valid()) {
+    surface_manager_->SurfaceDamageExpected(current_surface_id_, args);
+  }
+  last_begin_frame_args_ = args;
+  if (client_)
+    client_->OnBeginFrame(args);
+}
+
+const cc::BeginFrameArgs& CompositorFrameSinkSupport::LastUsedBeginFrameArgs()
+    const {
+  return last_begin_frame_args_;
+}
+
+void CompositorFrameSinkSupport::OnBeginFrameSourcePausedChanged(bool paused) {}
+
+void CompositorFrameSinkSupport::UpdateNeedsBeginFramesInternal() {
+  if (!begin_frame_source_)
+    return;
+
+  if (needs_begin_frame_ == added_frame_observer_)
+    return;
+
+  added_frame_observer_ = needs_begin_frame_;
+  if (needs_begin_frame_)
+    begin_frame_source_->AddObserver(this);
+  else
+    begin_frame_source_->RemoveObserver(this);
+}
+
+cc::Surface* CompositorFrameSinkSupport::CreateSurface(
+    const cc::SurfaceInfo& surface_info) {
+  seen_first_frame_activation_ = false;
+  return surface_manager_->CreateSurface(
+      weak_factory_.GetWeakPtr(), surface_info,
+      frame_sink_manager_->GetPrimaryBeginFrameSource(), needs_sync_tokens_);
+}
+
+void CompositorFrameSinkSupport::RequestCopyOfSurface(
+    std::unique_ptr<cc::CopyOutputRequest> copy_request) {
+  if (!current_surface_id_.is_valid())
+    return;
+  cc::Surface* current_surface =
+      surface_manager_->GetSurfaceForId(current_surface_id_);
+  current_surface->RequestCopyOfOutput(std::move(copy_request));
+  cc::BeginFrameAck ack;
+  ack.has_damage = true;
+  if (current_surface->HasActiveFrame())
+    surface_manager_->SurfaceModified(current_surface->surface_id(), ack);
+}
+
+cc::Surface* CompositorFrameSinkSupport::GetCurrentSurfaceForTesting() {
+  return surface_manager_->GetSurfaceForId(current_surface_id_);
+}
+
+}  // namespace viz
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support.h b/components/viz/service/frame_sinks/compositor_frame_sink_support.h
new file mode 100644
index 0000000..fd5e9a0
--- /dev/null
+++ b/components/viz/service/frame_sinks/compositor_frame_sink_support.h
@@ -0,0 +1,166 @@
+// 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 COMPONENTS_VIZ_SERVICE_FRAME_SINKS_COMPOSITOR_FRAME_SINK_SUPPORT_H_
+#define COMPONENTS_VIZ_SERVICE_FRAME_SINKS_COMPOSITOR_FRAME_SINK_SUPPORT_H_
+
+#include <memory>
+#include <unordered_set>
+#include <vector>
+
+#include "base/compiler_specific.h"
+#include "base/memory/weak_ptr.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/scheduler/begin_frame_source.h"
+#include "cc/surfaces/frame_sink_manager_client.h"
+#include "cc/surfaces/referenced_surface_tracker.h"
+#include "cc/surfaces/surface_client.h"
+#include "cc/surfaces/surface_info.h"
+#include "cc/surfaces/surface_resource_holder.h"
+#include "cc/surfaces/surface_resource_holder_client.h"
+#include "components/viz/service/viz_service_export.h"
+
+namespace cc {
+class FrameSinkManager;
+class Surface;
+class SurfaceManager;
+}  // namespace cc
+
+namespace viz {
+class CompositorFrameSinkSupportClient;
+
+class VIZ_SERVICE_EXPORT CompositorFrameSinkSupport
+    : public cc::BeginFrameObserver,
+      public cc::SurfaceResourceHolderClient,
+      public cc::FrameSinkManagerClient,
+      public cc::SurfaceClient {
+ public:
+  static std::unique_ptr<CompositorFrameSinkSupport> Create(
+      CompositorFrameSinkSupportClient* client,
+      cc::FrameSinkManager* frame_sink_manager,
+      const FrameSinkId& frame_sink_id,
+      bool is_root,
+      bool handles_frame_sink_id_invalidation,
+      bool needs_sync_tokens);
+
+  ~CompositorFrameSinkSupport() override;
+
+  const FrameSinkId& frame_sink_id() const { return frame_sink_id_; }
+
+  cc::FrameSinkManager* frame_sink_manager() { return frame_sink_manager_; }
+  cc::SurfaceManager* surface_manager() { return surface_manager_; }
+
+  // SurfaceClient implementation.
+  void OnSurfaceActivated(cc::Surface* surface) override;
+  void RefResources(
+      const std::vector<cc::TransferableResource>& resources) override;
+  void UnrefResources(
+      const std::vector<cc::ReturnedResource>& resources) override;
+  void ReturnResources(
+      const std::vector<cc::ReturnedResource>& resources) override;
+  void ReceiveFromChild(
+      const std::vector<cc::TransferableResource>& resources) override;
+
+  // FrameSinkManagerClient implementation.
+  void SetBeginFrameSource(cc::BeginFrameSource* begin_frame_source) override;
+
+  void EvictCurrentSurface();
+  void SetNeedsBeginFrame(bool needs_begin_frame);
+  void DidNotProduceFrame(const cc::BeginFrameAck& ack);
+  bool SubmitCompositorFrame(const LocalSurfaceId& local_surface_id,
+                             cc::CompositorFrame frame);
+  void RequestCopyOfSurface(std::unique_ptr<cc::CopyOutputRequest> request);
+  void ClaimTemporaryReference(const SurfaceId& surface_id);
+
+  cc::Surface* GetCurrentSurfaceForTesting();
+
+ protected:
+  CompositorFrameSinkSupport(CompositorFrameSinkSupportClient* client,
+                             const FrameSinkId& frame_sink_id,
+                             bool is_root,
+                             bool handles_frame_sink_id_invalidation,
+                             bool needs_sync_tokens);
+
+  void Init(cc::FrameSinkManager* frame_sink_manager);
+
+ private:
+  // Updates surface references using |active_referenced_surfaces| from the most
+  // recent CompositorFrame. This will add and remove top-level root references
+  // if |is_root_| is true and |local_surface_id| has changed. Modifies surface
+  // references stored in SurfaceManager.
+  void UpdateSurfaceReferences(
+      const LocalSurfaceId& local_surface_id,
+      const std::vector<SurfaceId>& active_referenced_surfaces);
+
+  // Creates a surface reference from the top-level root to |surface_id|.
+  cc::SurfaceReference MakeTopLevelRootReference(const SurfaceId& surface_id);
+
+  void DidReceiveCompositorFrameAck();
+  void WillDrawSurface(const LocalSurfaceId& local_surface_id,
+                       const gfx::Rect& damage_rect);
+
+  // BeginFrameObserver implementation.
+  void OnBeginFrame(const cc::BeginFrameArgs& args) override;
+  const cc::BeginFrameArgs& LastUsedBeginFrameArgs() const override;
+  void OnBeginFrameSourcePausedChanged(bool paused) override;
+
+  void UpdateNeedsBeginFramesInternal();
+  cc::Surface* CreateSurface(const cc::SurfaceInfo& surface_info);
+
+  CompositorFrameSinkSupportClient* const client_;
+
+  cc::FrameSinkManager* frame_sink_manager_ = nullptr;
+  cc::SurfaceManager* surface_manager_ = nullptr;
+
+  const FrameSinkId frame_sink_id_;
+  SurfaceId current_surface_id_;
+
+  // If this contains a value then a surface reference from the top-level root
+  // to SurfaceId(frame_sink_id_, referenced_local_surface_id_.value()) was
+  // added. This will not contain a value if |is_root_| is false.
+  base::Optional<LocalSurfaceId> referenced_local_surface_id_;
+
+  cc::SurfaceResourceHolder surface_resource_holder_;
+
+  // Counts the number of CompositorFrames that have been submitted and have not
+  // yet received an ACK.
+  int ack_pending_count_ = 0;
+  std::vector<cc::ReturnedResource> surface_returned_resources_;
+
+  // The begin frame source being observered. Null if none.
+  cc::BeginFrameSource* begin_frame_source_ = nullptr;
+
+  // The last begin frame args generated by the begin frame source.
+  cc::BeginFrameArgs last_begin_frame_args_;
+
+  // Whether a request for begin frames has been issued.
+  bool needs_begin_frame_ = false;
+
+  // Whether or not a frame observer has been added.
+  bool added_frame_observer_ = false;
+
+  const bool is_root_;
+  const bool needs_sync_tokens_;
+  bool seen_first_frame_activation_ = false;
+
+  // TODO(staraz): Remove this flag once ui::Compositor no longer needs to call
+  // RegisterFrameSinkId().
+  // A surfaceSequence's validity is bound to the lifetime of the parent
+  // FrameSink that created it. We track the lifetime of FrameSinks through
+  // RegisterFrameSinkId and InvalidateFrameSinkId. During startup and GPU
+  // restart, a SurfaceSequence created by the top most layer compositor may be
+  // used prior to the creation of the associated CompositorFrameSinkSupport.
+  // CompositorFrameSinkSupport is created asynchronously when a new GPU channel
+  // is established. Once we switch to SurfaceReferences, this ordering concern
+  // goes away and we can remove this bool.
+  const bool handles_frame_sink_id_invalidation_;
+
+  base::WeakPtrFactory<CompositorFrameSinkSupport> weak_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(CompositorFrameSinkSupport);
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_SERVICE_FRAME_SINKS_COMPOSITOR_FRAME_SINK_SUPPORT_H_
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support_client.h b/components/viz/service/frame_sinks/compositor_frame_sink_support_client.h
new file mode 100644
index 0000000..fa0f4782
--- /dev/null
+++ b/components/viz/service/frame_sinks/compositor_frame_sink_support_client.h
@@ -0,0 +1,50 @@
+// 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 COMPONENTS_VIZ_SERVICE_FRAME_SINKS_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_
+#define COMPONENTS_VIZ_SERVICE_FRAME_SINKS_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_
+
+#include "cc/resources/returned_resource.h"
+
+namespace cc {
+struct BeginFrameArgs;
+}  // namespace cc
+
+namespace gfx {
+class Rect;
+}
+
+namespace viz {
+class LocalSurfaceId;
+
+class CompositorFrameSinkSupportClient {
+ public:
+  // Notification that the previous CompositorFrame given to
+  // SubmitCompositorFrame() has been processed and that another frame
+  // can be submitted. This provides backpressure from the display compositor
+  // so that frames are submitted only at the rate it can handle them.
+  // TODO(fsamuel): This method ought not be necessary with unified BeginFrame.
+  // However, there's a fair amount of cleanup and refactoring necessary to get
+  // rid of it.
+  virtual void DidReceiveCompositorFrameAck(
+      const std::vector<cc::ReturnedResource>& resources) = 0;
+
+  // Notification for the client to generate a CompositorFrame.
+  virtual void OnBeginFrame(const cc::BeginFrameArgs& args) = 0;
+
+  // Returns resources sent to SubmitCompositorFrame to be reused or freed.
+  virtual void ReclaimResources(
+      const std::vector<cc::ReturnedResource>& resources) = 0;
+
+  // Called when surface is being scheduled for a draw.
+  virtual void WillDrawSurface(const LocalSurfaceId& local_surface_id,
+                               const gfx::Rect& damage_rect) = 0;
+
+ protected:
+  virtual ~CompositorFrameSinkSupportClient() {}
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_SERVICE_FRAME_SINKS_COMPOSITOR_FRAME_SINK_SUPPORT_CLIENT_H_
diff --git a/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc b/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc
new file mode 100644
index 0000000..ad8715c
--- /dev/null
+++ b/components/viz/service/frame_sinks/compositor_frame_sink_support_unittest.cc
@@ -0,0 +1,891 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
+
+#include "base/macros.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/output/copy_output_request.h"
+#include "cc/output/copy_output_result.h"
+#include "cc/resources/resource_provider.h"
+#include "cc/surfaces/frame_sink_manager.h"
+#include "cc/surfaces/surface_info.h"
+#include "cc/test/begin_frame_args_test.h"
+#include "cc/test/compositor_frame_helpers.h"
+#include "cc/test/fake_external_begin_frame_source.h"
+#include "cc/test/fake_surface_observer.h"
+#include "cc/test/mock_compositor_frame_sink_support_client.h"
+#include "components/viz/common/frame_sink_id.h"
+#include "components/viz/common/surface_id.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::UnorderedElementsAre;
+using testing::IsEmpty;
+using testing::SizeIs;
+using testing::Invoke;
+using testing::_;
+using testing::Eq;
+
+namespace viz {
+namespace {
+
+constexpr bool kIsRoot = true;
+constexpr bool kIsChildRoot = false;
+constexpr bool kHandlesFrameSinkIdInvalidation = true;
+constexpr bool kNeedsSyncPoints = true;
+
+constexpr FrameSinkId kArbitraryFrameSinkId(1, 1);
+constexpr FrameSinkId kAnotherArbitraryFrameSinkId(2, 2);
+constexpr FrameSinkId kYetAnotherArbitraryFrameSinkId(3, 3);
+
+const base::UnguessableToken kArbitraryToken = base::UnguessableToken::Create();
+const base::UnguessableToken kArbitrarySourceId1 =
+    base::UnguessableToken::Deserialize(0xdead, 0xbeef);
+const base::UnguessableToken kArbitrarySourceId2 =
+    base::UnguessableToken::Deserialize(0xdead, 0xbee0);
+
+gpu::SyncToken GenTestSyncToken(int id) {
+  gpu::SyncToken token;
+  token.Set(gpu::CommandBufferNamespace::GPU_IO, 0,
+            gpu::CommandBufferId::FromUnsafeValue(id), 1);
+  return token;
+}
+
+class FakeCompositorFrameSinkSupportClient
+    : public CompositorFrameSinkSupportClient {
+ public:
+  FakeCompositorFrameSinkSupportClient() = default;
+  ~FakeCompositorFrameSinkSupportClient() override = default;
+
+  void DidReceiveCompositorFrameAck(
+      const std::vector<cc::ReturnedResource>& resources) override {
+    InsertResources(resources);
+  }
+
+  void OnBeginFrame(const cc::BeginFrameArgs& args) override {}
+
+  void ReclaimResources(
+      const std::vector<cc::ReturnedResource>& resources) override {
+    InsertResources(resources);
+  }
+
+  void WillDrawSurface(const LocalSurfaceId& local_surface_id,
+                       const gfx::Rect& damage_rect) override {}
+
+  void clear_returned_resources() { returned_resources_.clear(); }
+  const std::vector<cc::ReturnedResource>& returned_resources() {
+    return returned_resources_;
+  }
+
+ private:
+  void InsertResources(const std::vector<cc::ReturnedResource>& resources) {
+    returned_resources_.insert(returned_resources_.end(), resources.begin(),
+                               resources.end());
+  }
+
+  std::vector<cc::ReturnedResource> returned_resources_;
+
+  DISALLOW_COPY_AND_ASSIGN(FakeCompositorFrameSinkSupportClient);
+};
+
+class CompositorFrameSinkSupportTest : public testing::Test {
+ public:
+  CompositorFrameSinkSupportTest()
+      : support_(
+            CompositorFrameSinkSupport::Create(&fake_support_client_,
+                                               &manager_,
+                                               kArbitraryFrameSinkId,
+                                               kIsRoot,
+                                               kHandlesFrameSinkIdInvalidation,
+                                               kNeedsSyncPoints)),
+        begin_frame_source_(0.f, false),
+        local_surface_id_(3, kArbitraryToken),
+        frame_sync_token_(GenTestSyncToken(4)),
+        consumer_sync_token_(GenTestSyncToken(5)) {
+    manager_.surface_manager()->AddObserver(&surface_observer_);
+    support_->SetBeginFrameSource(&begin_frame_source_);
+  }
+  ~CompositorFrameSinkSupportTest() override {
+    manager_.surface_manager()->RemoveObserver(&surface_observer_);
+    support_->EvictCurrentSurface();
+  }
+
+  void SubmitCompositorFrameWithResources(cc::ResourceId* resource_ids,
+                                          size_t num_resource_ids) {
+    auto frame = cc::test::MakeCompositorFrame();
+    for (size_t i = 0u; i < num_resource_ids; ++i) {
+      cc::TransferableResource resource;
+      resource.id = resource_ids[i];
+      resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
+      resource.mailbox_holder.sync_token = frame_sync_token_;
+      frame.resource_list.push_back(resource);
+    }
+    support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
+    EXPECT_EQ(surface_observer_.last_created_surface_id().local_surface_id(),
+              local_surface_id_);
+  }
+
+  void UnrefResources(cc::ResourceId* ids_to_unref,
+                      int* counts_to_unref,
+                      size_t num_ids_to_unref) {
+    std::vector<cc::ReturnedResource> unref_array;
+    for (size_t i = 0; i < num_ids_to_unref; ++i) {
+      cc::ReturnedResource resource;
+      resource.sync_token = consumer_sync_token_;
+      resource.id = ids_to_unref[i];
+      resource.count = counts_to_unref[i];
+      unref_array.push_back(resource);
+    }
+    support_->UnrefResources(unref_array);
+  }
+
+  void CheckReturnedResourcesMatchExpected(
+      cc::ResourceId* expected_returned_ids,
+      int* expected_returned_counts,
+      size_t expected_resources,
+      gpu::SyncToken expected_sync_token) {
+    const std::vector<cc::ReturnedResource>& actual_resources =
+        fake_support_client_.returned_resources();
+    ASSERT_EQ(expected_resources, actual_resources.size());
+    for (size_t i = 0; i < expected_resources; ++i) {
+      cc::ReturnedResource resource = actual_resources[i];
+      EXPECT_EQ(expected_sync_token, resource.sync_token);
+      EXPECT_EQ(expected_returned_ids[i], resource.id);
+      EXPECT_EQ(expected_returned_counts[i], resource.count);
+    }
+    fake_support_client_.clear_returned_resources();
+  }
+
+  cc::Surface* GetSurfaceForId(const SurfaceId& id) {
+    return manager_.surface_manager()->GetSurfaceForId(id);
+  }
+
+  void RefCurrentFrameResources() {
+    cc::Surface* surface = GetSurfaceForId(
+        SurfaceId(support_->frame_sink_id(), local_surface_id_));
+    support_->RefResources(surface->GetActiveFrame().resource_list);
+  }
+
+ protected:
+  cc::FrameSinkManager manager_;
+  FakeCompositorFrameSinkSupportClient fake_support_client_;
+  std::unique_ptr<CompositorFrameSinkSupport> support_;
+  cc::FakeExternalBeginFrameSource begin_frame_source_;
+  LocalSurfaceId local_surface_id_;
+  cc::FakeSurfaceObserver surface_observer_;
+
+  // This is the sync token submitted with the frame. It should never be
+  // returned to the client.
+  const gpu::SyncToken frame_sync_token_;
+
+  // This is the sync token returned by the consumer. It should always be
+  // returned to the client.
+  const gpu::SyncToken consumer_sync_token_;
+};
+
+// Tests submitting a frame with resources followed by one with no resources
+// with no resource provider action in between.
+TEST_F(CompositorFrameSinkSupportTest, ResourceLifetimeSimple) {
+  cc::ResourceId first_frame_ids[] = {1, 2, 3};
+  SubmitCompositorFrameWithResources(first_frame_ids,
+                                     arraysize(first_frame_ids));
+
+  // All of the resources submitted in the first frame are still in use at this
+  // time by virtue of being in the pending frame, so none can be returned to
+  // the client yet.
+  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
+  fake_support_client_.clear_returned_resources();
+
+  // The second frame references no resources of first frame and thus should
+  // make all resources of first frame available to be returned.
+  SubmitCompositorFrameWithResources(NULL, 0);
+
+  cc::ResourceId expected_returned_ids[] = {1, 2, 3};
+  int expected_returned_counts[] = {1, 1, 1};
+  // Resources were never consumed so no sync token should be set.
+  CheckReturnedResourcesMatchExpected(
+      expected_returned_ids, expected_returned_counts,
+      arraysize(expected_returned_counts), gpu::SyncToken());
+
+  cc::ResourceId third_frame_ids[] = {4, 5, 6};
+  SubmitCompositorFrameWithResources(third_frame_ids,
+                                     arraysize(third_frame_ids));
+
+  // All of the resources submitted in the third frame are still in use at this
+  // time by virtue of being in the pending frame, so none can be returned to
+  // the client yet.
+  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
+  fake_support_client_.clear_returned_resources();
+
+  // The forth frame references no resources of third frame and thus should
+  // make all resources of third frame available to be returned.
+  cc::ResourceId forth_frame_ids[] = {7, 8, 9};
+  SubmitCompositorFrameWithResources(forth_frame_ids,
+                                     arraysize(forth_frame_ids));
+
+  cc::ResourceId forth_expected_returned_ids[] = {4, 5, 6};
+  int forth_expected_returned_counts[] = {1, 1, 1};
+  // Resources were never consumed so no sync token should be set.
+  CheckReturnedResourcesMatchExpected(
+      forth_expected_returned_ids, forth_expected_returned_counts,
+      arraysize(forth_expected_returned_counts), gpu::SyncToken());
+}
+
+// Tests submitting a frame with resources followed by one with no resources
+// with the resource provider holding everything alive.
+TEST_F(CompositorFrameSinkSupportTest,
+       ResourceLifetimeSimpleWithProviderHoldingAlive) {
+  cc::ResourceId first_frame_ids[] = {1, 2, 3};
+  SubmitCompositorFrameWithResources(first_frame_ids,
+                                     arraysize(first_frame_ids));
+
+  // All of the resources submitted in the first frame are still in use at this
+  // time by virtue of being in the pending frame, so none can be returned to
+  // the client yet.
+  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
+  fake_support_client_.clear_returned_resources();
+
+  // Hold on to everything.
+  RefCurrentFrameResources();
+
+  // The second frame references no resources and thus should make all resources
+  // available to be returned as soon as the resource provider releases them.
+  SubmitCompositorFrameWithResources(NULL, 0);
+
+  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
+  fake_support_client_.clear_returned_resources();
+
+  int release_counts[] = {1, 1, 1};
+  UnrefResources(first_frame_ids, release_counts, arraysize(first_frame_ids));
+
+  // None is returned to the client since DidReceiveCompositorAck is not
+  // invoked.
+  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
+
+  // Submitting an empty frame causes previous resources referenced by the
+  // previous frame to be returned to client.
+  SubmitCompositorFrameWithResources(nullptr, 0);
+  cc::ResourceId expected_returned_ids[] = {1, 2, 3};
+  int expected_returned_counts[] = {1, 1, 1};
+  CheckReturnedResourcesMatchExpected(
+      expected_returned_ids, expected_returned_counts,
+      arraysize(expected_returned_counts), consumer_sync_token_);
+}
+
+// Tests referencing a resource, unref'ing it to zero, then using it again
+// before returning it to the client.
+TEST_F(CompositorFrameSinkSupportTest, ResourceReusedBeforeReturn) {
+  cc::ResourceId first_frame_ids[] = {7};
+  SubmitCompositorFrameWithResources(first_frame_ids,
+                                     arraysize(first_frame_ids));
+
+  // This removes all references to resource id 7.
+  SubmitCompositorFrameWithResources(NULL, 0);
+
+  // This references id 7 again.
+  SubmitCompositorFrameWithResources(first_frame_ids,
+                                     arraysize(first_frame_ids));
+
+  // This removes it again.
+  SubmitCompositorFrameWithResources(NULL, 0);
+
+  // Now it should be returned.
+  // We don't care how many entries are in the returned array for 7, so long as
+  // the total returned count matches the submitted count.
+  const std::vector<cc::ReturnedResource>& returned =
+      fake_support_client_.returned_resources();
+  size_t return_count = 0;
+  for (size_t i = 0; i < returned.size(); ++i) {
+    EXPECT_EQ(7u, returned[i].id);
+    return_count += returned[i].count;
+  }
+  EXPECT_EQ(2u, return_count);
+}
+
+// Tests having resources referenced multiple times, as if referenced by
+// multiple providers.
+TEST_F(CompositorFrameSinkSupportTest, ResourceRefMultipleTimes) {
+  cc::ResourceId first_frame_ids[] = {3, 4};
+  SubmitCompositorFrameWithResources(first_frame_ids,
+                                     arraysize(first_frame_ids));
+
+  // Ref resources from the first frame twice.
+  RefCurrentFrameResources();
+  RefCurrentFrameResources();
+
+  cc::ResourceId second_frame_ids[] = {4, 5};
+  SubmitCompositorFrameWithResources(second_frame_ids,
+                                     arraysize(second_frame_ids));
+
+  // Ref resources from the second frame 3 times.
+  RefCurrentFrameResources();
+  RefCurrentFrameResources();
+  RefCurrentFrameResources();
+
+  // Submit a frame with no resources to remove all current frame refs from
+  // submitted resources.
+  SubmitCompositorFrameWithResources(NULL, 0);
+
+  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
+  fake_support_client_.clear_returned_resources();
+
+  // Expected current refs:
+  //  3 -> 2
+  //  4 -> 2 + 3 = 5
+  //  5 -> 3
+  {
+    SCOPED_TRACE("unref all 3");
+    cc::ResourceId ids_to_unref[] = {3, 4, 5};
+    int counts[] = {1, 1, 1};
+    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
+
+    EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
+    fake_support_client_.clear_returned_resources();
+
+    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
+    SubmitCompositorFrameWithResources(nullptr, 0);
+    cc::ResourceId expected_returned_ids[] = {3};
+    int expected_returned_counts[] = {1};
+    CheckReturnedResourcesMatchExpected(
+        expected_returned_ids, expected_returned_counts,
+        arraysize(expected_returned_counts), consumer_sync_token_);
+  }
+
+  // Expected refs remaining:
+  //  4 -> 3
+  //  5 -> 1
+  {
+    SCOPED_TRACE("unref 4 and 5");
+    cc::ResourceId ids_to_unref[] = {4, 5};
+    int counts[] = {1, 1};
+    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
+    SubmitCompositorFrameWithResources(nullptr, 0);
+
+    cc::ResourceId expected_returned_ids[] = {5};
+    int expected_returned_counts[] = {1};
+    CheckReturnedResourcesMatchExpected(
+        expected_returned_ids, expected_returned_counts,
+        arraysize(expected_returned_counts), consumer_sync_token_);
+  }
+
+  // Now, just 2 refs remaining on resource 4. Unref both at once and make sure
+  // the returned count is correct.
+  {
+    SCOPED_TRACE("unref only 4");
+    cc::ResourceId ids_to_unref[] = {4};
+    int counts[] = {2};
+    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
+    SubmitCompositorFrameWithResources(nullptr, 0);
+
+    cc::ResourceId expected_returned_ids[] = {4};
+    int expected_returned_counts[] = {2};
+    CheckReturnedResourcesMatchExpected(
+        expected_returned_ids, expected_returned_counts,
+        arraysize(expected_returned_counts), consumer_sync_token_);
+  }
+}
+
+TEST_F(CompositorFrameSinkSupportTest, ResourceLifetime) {
+  cc::ResourceId first_frame_ids[] = {1, 2, 3};
+  SubmitCompositorFrameWithResources(first_frame_ids,
+                                     arraysize(first_frame_ids));
+
+  // All of the resources submitted in the first frame are still in use at this
+  // time by virtue of being in the pending frame, so none can be returned to
+  // the client yet.
+  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
+  fake_support_client_.clear_returned_resources();
+
+  // The second frame references some of the same resources, but some different
+  // ones. We expect to receive back resource 1 with a count of 1 since it was
+  // only referenced by the first frame.
+  cc::ResourceId second_frame_ids[] = {2, 3, 4};
+  SubmitCompositorFrameWithResources(second_frame_ids,
+                                     arraysize(second_frame_ids));
+  {
+    SCOPED_TRACE("second frame");
+    cc::ResourceId expected_returned_ids[] = {1};
+    int expected_returned_counts[] = {1};
+    CheckReturnedResourcesMatchExpected(
+        expected_returned_ids, expected_returned_counts,
+        arraysize(expected_returned_counts), gpu::SyncToken());
+  }
+
+  // The third frame references a disjoint set of resources, so we expect to
+  // receive back all resources from the first and second frames. Resource IDs 2
+  // and 3 will have counts of 2, since they were used in both frames, and
+  // resource ID 4 will have a count of 1.
+  cc::ResourceId third_frame_ids[] = {10, 11, 12, 13};
+  SubmitCompositorFrameWithResources(third_frame_ids,
+                                     arraysize(third_frame_ids));
+
+  {
+    SCOPED_TRACE("third frame");
+    cc::ResourceId expected_returned_ids[] = {2, 3, 4};
+    int expected_returned_counts[] = {2, 2, 1};
+    CheckReturnedResourcesMatchExpected(
+        expected_returned_ids, expected_returned_counts,
+        arraysize(expected_returned_counts), gpu::SyncToken());
+  }
+
+  // Simulate a ResourceProvider taking a ref on all of the resources.
+  RefCurrentFrameResources();
+
+  cc::ResourceId fourth_frame_ids[] = {12, 13};
+  SubmitCompositorFrameWithResources(fourth_frame_ids,
+                                     arraysize(fourth_frame_ids));
+
+  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
+
+  RefCurrentFrameResources();
+
+  // All resources are still being used by the external reference, so none can
+  // be returned to the client.
+  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
+
+  // Release resources associated with the first RefCurrentFrameResources() call
+  // first.
+  {
+    cc::ResourceId ids_to_unref[] = {10, 11, 12, 13};
+    int counts[] = {1, 1, 1, 1};
+    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
+  }
+
+  // Nothing is returned to the client yet since DidReceiveCompositorFrameAck
+  // is not invoked.
+  {
+    SCOPED_TRACE("fourth frame, first unref");
+    CheckReturnedResourcesMatchExpected(nullptr, nullptr, 0,
+                                        consumer_sync_token_);
+  }
+
+  {
+    cc::ResourceId ids_to_unref[] = {12, 13};
+    int counts[] = {1, 1};
+    UnrefResources(ids_to_unref, counts, arraysize(ids_to_unref));
+  }
+
+  // Resources 12 and 13 are still in use by the current frame, so they
+  // shouldn't be available to be returned.
+  EXPECT_EQ(0u, fake_support_client_.returned_resources().size());
+
+  // If we submit an empty frame, however, they should become available.
+  // Resources that were previously unref'd also return at this point.
+  SubmitCompositorFrameWithResources(NULL, 0u);
+
+  {
+    SCOPED_TRACE("fourth frame, second unref");
+    cc::ResourceId expected_returned_ids[] = {10, 11, 12, 13};
+    int expected_returned_counts[] = {1, 1, 2, 2};
+    CheckReturnedResourcesMatchExpected(
+        expected_returned_ids, expected_returned_counts,
+        arraysize(expected_returned_counts), consumer_sync_token_);
+  }
+}
+
+TEST_F(CompositorFrameSinkSupportTest, AddDuringEviction) {
+  cc::test::MockCompositorFrameSinkSupportClient mock_client;
+  auto support = CompositorFrameSinkSupport::Create(
+      &mock_client, &manager_, kAnotherArbitraryFrameSinkId, kIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId local_surface_id(6, kArbitraryToken);
+  support->SubmitCompositorFrame(local_surface_id,
+                                 cc::test::MakeCompositorFrame());
+
+  EXPECT_CALL(mock_client, DidReceiveCompositorFrameAck(_))
+      .WillOnce(testing::InvokeWithoutArgs([&support, &mock_client]() {
+        LocalSurfaceId new_id(7, base::UnguessableToken::Create());
+        support->SubmitCompositorFrame(new_id, cc::test::MakeCompositorFrame());
+      }))
+      .WillRepeatedly(testing::Return());
+  support->EvictCurrentSurface();
+}
+
+// Tests doing an EvictCurrentSurface before shutting down the factory.
+TEST_F(CompositorFrameSinkSupportTest, EvictCurrentSurface) {
+  cc::test::MockCompositorFrameSinkSupportClient mock_client;
+  auto support = CompositorFrameSinkSupport::Create(
+      &mock_client, &manager_, kAnotherArbitraryFrameSinkId, kIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId local_surface_id(7, kArbitraryToken);
+  SurfaceId id(kAnotherArbitraryFrameSinkId, local_surface_id);
+
+  cc::TransferableResource resource;
+  resource.id = 1;
+  resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
+  auto frame = cc::test::MakeCompositorFrame();
+  frame.resource_list.push_back(resource);
+  support->SubmitCompositorFrame(local_surface_id, std::move(frame));
+  EXPECT_EQ(surface_observer_.last_created_surface_id().local_surface_id(),
+            local_surface_id);
+  local_surface_id_ = LocalSurfaceId();
+
+  std::vector<cc::ReturnedResource> returned_resources = {
+      resource.ToReturnedResource()};
+  EXPECT_TRUE(GetSurfaceForId(id));
+  EXPECT_CALL(mock_client, DidReceiveCompositorFrameAck(returned_resources))
+      .Times(1);
+  support->EvictCurrentSurface();
+  EXPECT_FALSE(GetSurfaceForId(id));
+}
+
+// Tests doing an EvictCurrentSurface which has unregistered dependency.
+TEST_F(CompositorFrameSinkSupportTest,
+       EvictCurrentSurfaceDependencyUnRegistered) {
+  cc::test::MockCompositorFrameSinkSupportClient mock_client;
+  auto support = CompositorFrameSinkSupport::Create(
+      &mock_client, &manager_, kAnotherArbitraryFrameSinkId, kIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId local_surface_id(7, kArbitraryToken);
+
+  cc::TransferableResource resource;
+  resource.id = 1;
+  resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
+  auto frame = cc::test::MakeCompositorFrame();
+  frame.resource_list.push_back(resource);
+  support->SubmitCompositorFrame(local_surface_id, std::move(frame));
+  EXPECT_EQ(surface_observer_.last_created_surface_id().local_surface_id(),
+            local_surface_id);
+  local_surface_id_ = LocalSurfaceId();
+
+  SurfaceId surface_id(kAnotherArbitraryFrameSinkId, local_surface_id);
+  cc::Surface* surface = GetSurfaceForId(surface_id);
+  surface->AddDestructionDependency(
+      cc::SurfaceSequence(kYetAnotherArbitraryFrameSinkId, 4));
+
+  std::vector<cc::ReturnedResource> returned_resource = {
+      resource.ToReturnedResource()};
+
+  EXPECT_TRUE(GetSurfaceForId(surface_id));
+  EXPECT_CALL(mock_client, DidReceiveCompositorFrameAck(returned_resource))
+      .Times(1);
+  support->EvictCurrentSurface();
+  EXPECT_FALSE(GetSurfaceForId(surface_id));
+}
+
+// Tests doing an EvictCurrentSurface which has registered dependency.
+TEST_F(CompositorFrameSinkSupportTest,
+       EvictCurrentSurfaceDependencyRegistered) {
+  cc::test::MockCompositorFrameSinkSupportClient mock_client;
+  auto support = CompositorFrameSinkSupport::Create(
+      &mock_client, &manager_, kAnotherArbitraryFrameSinkId, kIsRoot,
+      kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  LocalSurfaceId local_surface_id(7, kArbitraryToken);
+
+  cc::TransferableResource resource;
+  resource.id = 1;
+  resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
+  auto frame = cc::test::MakeCompositorFrame();
+  frame.resource_list.push_back(resource);
+  uint32_t execute_count = 0;
+  support->SubmitCompositorFrame(local_surface_id, std::move(frame));
+  EXPECT_EQ(surface_observer_.last_created_surface_id().local_surface_id(),
+            local_surface_id);
+  local_surface_id_ = LocalSurfaceId();
+
+  manager_.RegisterFrameSinkId(kYetAnotherArbitraryFrameSinkId);
+
+  SurfaceId surface_id(kAnotherArbitraryFrameSinkId, local_surface_id);
+  cc::Surface* surface = GetSurfaceForId(surface_id);
+  surface->AddDestructionDependency(
+      cc::SurfaceSequence(kYetAnotherArbitraryFrameSinkId, 4));
+
+  std::vector<cc::ReturnedResource> returned_resources;
+  EXPECT_TRUE(GetSurfaceForId(surface_id));
+  support->EvictCurrentSurface();
+  EXPECT_TRUE(GetSurfaceForId(surface_id));
+  EXPECT_EQ(0u, execute_count);
+
+  returned_resources.push_back(resource.ToReturnedResource());
+  EXPECT_CALL(mock_client, DidReceiveCompositorFrameAck(returned_resources))
+      .Times(1);
+  manager_.surface_manager()->SatisfySequence(
+      cc::SurfaceSequence(kYetAnotherArbitraryFrameSinkId, 4));
+  EXPECT_FALSE(GetSurfaceForId(surface_id));
+}
+
+TEST_F(CompositorFrameSinkSupportTest, DestroySequence) {
+  LocalSurfaceId local_surface_id2(5, kArbitraryToken);
+  auto support2 = CompositorFrameSinkSupport::Create(
+      &fake_support_client_, &manager_, kYetAnotherArbitraryFrameSinkId,
+      kIsChildRoot, kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  SurfaceId id2(kYetAnotherArbitraryFrameSinkId, local_surface_id2);
+  support2->SubmitCompositorFrame(local_surface_id2,
+                                  cc::test::MakeCompositorFrame());
+
+  // Check that waiting before the sequence is satisfied works.
+  GetSurfaceForId(id2)->AddDestructionDependency(
+      cc::SurfaceSequence(kYetAnotherArbitraryFrameSinkId, 4));
+  support2->EvictCurrentSurface();
+
+  DCHECK(GetSurfaceForId(id2));
+  manager_.surface_manager()->SatisfySequence(
+      cc::SurfaceSequence(kYetAnotherArbitraryFrameSinkId, 4));
+  manager_.surface_manager()->SatisfySequence(
+      cc::SurfaceSequence(kYetAnotherArbitraryFrameSinkId, 6));
+  DCHECK(!GetSurfaceForId(id2));
+
+  // Check that waiting after the sequence is satisfied works.
+  support2->SubmitCompositorFrame(local_surface_id2,
+                                  cc::test::MakeCompositorFrame());
+  DCHECK(GetSurfaceForId(id2));
+  GetSurfaceForId(id2)->AddDestructionDependency(
+      cc::SurfaceSequence(kAnotherArbitraryFrameSinkId, 6));
+  support2->EvictCurrentSurface();
+  DCHECK(!GetSurfaceForId(id2));
+}
+
+// Tests that SurfaceId namespace invalidation correctly allows
+// Sequences to be ignored.
+TEST_F(CompositorFrameSinkSupportTest, InvalidFrameSinkId) {
+  FrameSinkId frame_sink_id(1234, 5678);
+
+  LocalSurfaceId local_surface_id(5, kArbitraryToken);
+  SurfaceId id(support_->frame_sink_id(), local_surface_id);
+  support_->SubmitCompositorFrame(local_surface_id,
+                                  cc::test::MakeCompositorFrame());
+
+  manager_.RegisterFrameSinkId(frame_sink_id);
+  GetSurfaceForId(id)->AddDestructionDependency(
+      cc::SurfaceSequence(frame_sink_id, 4));
+
+  support_->EvictCurrentSurface();
+
+  // Verify the dependency has prevented the surface from getting destroyed.
+  EXPECT_TRUE(GetSurfaceForId(id));
+
+  manager_.InvalidateFrameSinkId(frame_sink_id);
+
+  // Verify that the invalidated namespace caused the unsatisfied sequence
+  // to be ignored.
+  EXPECT_FALSE(GetSurfaceForId(id));
+}
+
+TEST_F(CompositorFrameSinkSupportTest, DestroyCycle) {
+  LocalSurfaceId local_surface_id2(5, kArbitraryToken);
+  SurfaceId id2(kYetAnotherArbitraryFrameSinkId, local_surface_id2);
+  auto support2 = CompositorFrameSinkSupport::Create(
+      &fake_support_client_, &manager_, kYetAnotherArbitraryFrameSinkId,
+      kIsChildRoot, kHandlesFrameSinkIdInvalidation, kNeedsSyncPoints);
+  manager_.RegisterFrameSinkId(kAnotherArbitraryFrameSinkId);
+  // Give local_surface_id_ an initial frame so another client can refer to
+  // that surface.
+  {
+    auto frame = cc::test::MakeCompositorFrame();
+    support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
+  }
+  // Give id2 a frame that references local_surface_id_.
+  {
+    auto frame = cc::test::MakeCompositorFrame();
+    frame.metadata.referenced_surfaces.push_back(
+        SurfaceId(support_->frame_sink_id(), local_surface_id_));
+    support2->SubmitCompositorFrame(local_surface_id2, std::move(frame));
+    EXPECT_EQ(surface_observer_.last_created_surface_id().local_surface_id(),
+              local_surface_id2);
+  }
+  GetSurfaceForId(id2)->AddDestructionDependency(
+      cc::SurfaceSequence(kAnotherArbitraryFrameSinkId, 4));
+  support2->EvictCurrentSurface();
+  // Give local_surface_id_ a frame that references id2.
+  {
+    auto frame = cc::test::MakeCompositorFrame();
+    frame.metadata.referenced_surfaces.push_back(id2);
+    support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
+  }
+  support_->EvictCurrentSurface();
+  EXPECT_TRUE(GetSurfaceForId(id2));
+  // local_surface_id_ should be retained by reference from id2.
+  EXPECT_TRUE(
+      GetSurfaceForId(SurfaceId(support_->frame_sink_id(), local_surface_id_)));
+
+  // Satisfy last destruction dependency for id2.
+  manager_.surface_manager()->SatisfySequence(
+      cc::SurfaceSequence(kAnotherArbitraryFrameSinkId, 4));
+
+  // id2 and local_surface_id_ are in a reference cycle that has no surface
+  // sequences holding on to it, so they should be destroyed.
+  EXPECT_TRUE(!GetSurfaceForId(id2));
+  EXPECT_TRUE(!GetSurfaceForId(
+      SurfaceId(support_->frame_sink_id(), local_surface_id_)));
+
+  local_surface_id_ = LocalSurfaceId();
+}
+
+void CopyRequestTestCallback(bool* called,
+                             std::unique_ptr<cc::CopyOutputResult> result) {
+  *called = true;
+}
+
+TEST_F(CompositorFrameSinkSupportTest, DuplicateCopyRequest) {
+  {
+    auto frame = cc::test::MakeCompositorFrame();
+    frame.metadata.referenced_surfaces.push_back(
+        SurfaceId(support_->frame_sink_id(), local_surface_id_));
+    support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
+    EXPECT_EQ(surface_observer_.last_created_surface_id().local_surface_id(),
+              local_surface_id_);
+  }
+
+  bool called1 = false;
+  auto request = cc::CopyOutputRequest::CreateRequest(
+      base::Bind(&CopyRequestTestCallback, &called1));
+  request->set_source(kArbitrarySourceId1);
+
+  support_->RequestCopyOfSurface(std::move(request));
+  EXPECT_FALSE(called1);
+
+  bool called2 = false;
+  request = cc::CopyOutputRequest::CreateRequest(
+      base::Bind(&CopyRequestTestCallback, &called2));
+  request->set_source(kArbitrarySourceId2);
+
+  support_->RequestCopyOfSurface(std::move(request));
+  // Callbacks have different sources so neither should be called.
+  EXPECT_FALSE(called1);
+  EXPECT_FALSE(called2);
+
+  bool called3 = false;
+  request = cc::CopyOutputRequest::CreateRequest(
+      base::Bind(&CopyRequestTestCallback, &called3));
+  request->set_source(kArbitrarySourceId1);
+
+  support_->RequestCopyOfSurface(std::move(request));
+  // Two callbacks are from source1, so the first should be called.
+  EXPECT_TRUE(called1);
+  EXPECT_FALSE(called2);
+  EXPECT_FALSE(called3);
+
+  support_->EvictCurrentSurface();
+  local_surface_id_ = LocalSurfaceId();
+  EXPECT_TRUE(called1);
+  EXPECT_TRUE(called2);
+  EXPECT_TRUE(called3);
+}
+
+// Check whether the SurfaceInfo object is created and populated correctly
+// after the frame submission.
+TEST_F(CompositorFrameSinkSupportTest, SurfaceInfo) {
+  auto frame = cc::test::MakeCompositorFrame();
+
+  auto render_pass = cc::RenderPass::Create();
+  render_pass->SetNew(1, gfx::Rect(5, 6), gfx::Rect(), gfx::Transform());
+  frame.render_pass_list.push_back(std::move(render_pass));
+
+  render_pass = cc::RenderPass::Create();
+  render_pass->SetNew(2, gfx::Rect(7, 8), gfx::Rect(), gfx::Transform());
+  frame.render_pass_list.push_back(std::move(render_pass));
+
+  frame.metadata.device_scale_factor = 2.5f;
+
+  support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
+  SurfaceId expected_surface_id(support_->frame_sink_id(), local_surface_id_);
+  EXPECT_EQ(expected_surface_id, surface_observer_.last_surface_info().id());
+  EXPECT_EQ(2.5f, surface_observer_.last_surface_info().device_scale_factor());
+  EXPECT_EQ(gfx::Size(7, 8),
+            surface_observer_.last_surface_info().size_in_pixels());
+}
+
+// Check that if a CompositorFrame is received with size zero, we don't create
+// a Surface for it.
+TEST_F(CompositorFrameSinkSupportTest, ZeroFrameSize) {
+  SurfaceId id(support_->frame_sink_id(), local_surface_id_);
+  auto frame = cc::test::MakeEmptyCompositorFrame();
+  frame.render_pass_list.push_back(cc::RenderPass::Create());
+  EXPECT_TRUE(
+      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)));
+  EXPECT_FALSE(GetSurfaceForId(id));
+}
+
+// Check that if a CompositorFrame is received with device scale factor of 0, we
+// don't create a Surface for it.
+TEST_F(CompositorFrameSinkSupportTest, ZeroDeviceScaleFactor) {
+  SurfaceId id(support_->frame_sink_id(), local_surface_id_);
+  auto frame = cc::test::MakeCompositorFrame();
+  frame.metadata.device_scale_factor = 0.f;
+  EXPECT_TRUE(
+      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)));
+  EXPECT_FALSE(GetSurfaceForId(id));
+}
+
+// Check that if the size of a CompositorFrame doesn't match the size of the
+// Surface it's being submitted to, we skip the frame.
+TEST_F(CompositorFrameSinkSupportTest, FrameSizeMismatch) {
+  SurfaceId id(support_->frame_sink_id(), local_surface_id_);
+
+  // Submit a frame with size (5,5).
+  auto frame = cc::test::MakeEmptyCompositorFrame();
+  auto pass = cc::RenderPass::Create();
+  pass->SetNew(1, gfx::Rect(5, 5), gfx::Rect(), gfx::Transform());
+  frame.render_pass_list.push_back(std::move(pass));
+  EXPECT_TRUE(
+      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)));
+  EXPECT_TRUE(GetSurfaceForId(id));
+
+  // Submit a frame with size (5,4). This frame should be rejected and the
+  // surface should be destroyed.
+  frame = cc::test::MakeEmptyCompositorFrame();
+  pass = cc::RenderPass::Create();
+  pass->SetNew(1, gfx::Rect(5, 4), gfx::Rect(), gfx::Transform());
+  frame.render_pass_list.push_back(std::move(pass));
+  EXPECT_FALSE(
+      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)));
+  EXPECT_FALSE(GetSurfaceForId(id));
+}
+
+// Check that if the device scale factor of a CompositorFrame doesn't match the
+// device scale factor of the Surface it's being submitted to, the frame is
+// rejected and the surface is destroyed.
+TEST_F(CompositorFrameSinkSupportTest, DeviceScaleFactorMismatch) {
+  SurfaceId id(support_->frame_sink_id(), local_surface_id_);
+
+  // Submit a frame with device scale factor of 0.5.
+  auto frame = cc::test::MakeCompositorFrame();
+  frame.metadata.device_scale_factor = 0.5f;
+  EXPECT_TRUE(
+      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)));
+  EXPECT_TRUE(GetSurfaceForId(id));
+
+  // Submit a frame with device scale factor of 0.4. This frame should be
+  // rejected and the surface should be destroyed.
+  frame = cc::test::MakeCompositorFrame();
+  frame.metadata.device_scale_factor = 0.4f;
+  EXPECT_FALSE(
+      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame)));
+  EXPECT_FALSE(GetSurfaceForId(id));
+}
+
+TEST_F(CompositorFrameSinkSupportTest, PassesOnBeginFrameAcks) {
+  // Request BeginFrames.
+  support_->SetNeedsBeginFrame(true);
+
+  // Issue a BeginFrame.
+  cc::BeginFrameArgs args =
+      cc::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
+  begin_frame_source_.TestOnBeginFrame(args);
+
+  // Check that the support and SurfaceManager forward the BeginFrameAck
+  // attached to a CompositorFrame to the SurfaceObserver.
+  cc::BeginFrameAck ack(0, 1, 1, true);
+  auto frame = cc::test::MakeCompositorFrame();
+  frame.metadata.begin_frame_ack = ack;
+  support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
+  EXPECT_EQ(ack, surface_observer_.last_ack());
+
+  // Issue another BeginFrame.
+  args = cc::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2);
+  begin_frame_source_.TestOnBeginFrame(args);
+
+  // Check that the support and SurfaceManager forward a DidNotProduceFrame ack
+  // to the SurfaceObserver.
+  cc::BeginFrameAck ack2(0, 2, 2, false);
+  support_->DidNotProduceFrame(ack2);
+  EXPECT_EQ(ack2, surface_observer_.last_ack());
+
+  support_->SetNeedsBeginFrame(false);
+}
+
+}  // namespace
+}  // namespace viz
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
new file mode 100644
index 0000000..4a4f5bb9
--- /dev/null
+++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.cc
@@ -0,0 +1,165 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h"
+
+#include "base/bind.h"
+#include "cc/output/compositor_frame.h"
+#include "cc/output/layer_tree_frame_sink_client.h"
+#include "cc/surfaces/frame_sink_manager.h"
+#include "cc/surfaces/surface.h"
+#include "components/viz/common/frame_sink_id.h"
+#include "components/viz/common/local_surface_id_allocator.h"
+#include "components/viz/service/display/display.h"
+
+namespace viz {
+
+DirectLayerTreeFrameSink::DirectLayerTreeFrameSink(
+    const FrameSinkId& frame_sink_id,
+    cc::FrameSinkManager* frame_sink_manager,
+    Display* display,
+    scoped_refptr<cc::ContextProvider> context_provider,
+    scoped_refptr<cc::ContextProvider> worker_context_provider,
+    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
+    SharedBitmapManager* shared_bitmap_manager)
+    : LayerTreeFrameSink(std::move(context_provider),
+                         std::move(worker_context_provider),
+                         gpu_memory_buffer_manager,
+                         shared_bitmap_manager),
+      frame_sink_id_(frame_sink_id),
+      frame_sink_manager_(frame_sink_manager),
+      display_(display) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  capabilities_.must_always_swap = true;
+  // Display and DirectLayerTreeFrameSink share a GL context, so sync
+  // points aren't needed when passing resources between them.
+  capabilities_.delegated_sync_points_required = false;
+}
+
+DirectLayerTreeFrameSink::DirectLayerTreeFrameSink(
+    const FrameSinkId& frame_sink_id,
+    cc::FrameSinkManager* frame_sink_manager,
+    Display* display,
+    scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider)
+    : LayerTreeFrameSink(std::move(vulkan_context_provider)),
+      frame_sink_id_(frame_sink_id),
+      frame_sink_manager_(frame_sink_manager),
+      display_(display) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+  capabilities_.must_always_swap = true;
+}
+
+DirectLayerTreeFrameSink::~DirectLayerTreeFrameSink() {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+}
+
+bool DirectLayerTreeFrameSink::BindToClient(
+    cc::LayerTreeFrameSinkClient* client) {
+  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
+
+  if (!cc::LayerTreeFrameSink::BindToClient(client))
+    return false;
+
+  // We want the Display's output surface to hear about lost context, and since
+  // this shares a context with it, we should not be listening for lost context
+  // callbacks on the context here.
+  if (auto* cp = context_provider())
+    cp->SetLostContextCallback(base::Closure());
+
+  constexpr bool is_root = true;
+  constexpr bool handles_frame_sink_id_invalidation = false;
+  support_ = CompositorFrameSinkSupport::Create(
+      this, frame_sink_manager_, frame_sink_id_, is_root,
+      handles_frame_sink_id_invalidation,
+      capabilities_.delegated_sync_points_required);
+  begin_frame_source_ = base::MakeUnique<cc::ExternalBeginFrameSource>(this);
+  client_->SetBeginFrameSource(begin_frame_source_.get());
+
+  // Avoid initializing GL context here, as this should be sharing the
+  // Display's context.
+  display_->Initialize(this, frame_sink_manager_->surface_manager());
+  return true;
+}
+
+void DirectLayerTreeFrameSink::DetachFromClient() {
+  client_->SetBeginFrameSource(nullptr);
+  begin_frame_source_.reset();
+
+  // Unregister the SurfaceFactoryClient here instead of the dtor so that only
+  // one client is alive for this namespace at any given time.
+  support_.reset();
+
+  cc::LayerTreeFrameSink::DetachFromClient();
+}
+
+void DirectLayerTreeFrameSink::SubmitCompositorFrame(
+    cc::CompositorFrame frame) {
+  DCHECK(frame.metadata.begin_frame_ack.has_damage);
+  DCHECK_LE(cc::BeginFrameArgs::kStartingFrameNumber,
+            frame.metadata.begin_frame_ack.sequence_number);
+
+  gfx::Size frame_size = frame.render_pass_list.back()->output_rect.size();
+  if (!local_surface_id_.is_valid() || frame_size != last_swap_frame_size_ ||
+      frame.metadata.device_scale_factor != device_scale_factor_) {
+    local_surface_id_ = local_surface_id_allocator_.GenerateId();
+    last_swap_frame_size_ = frame_size;
+    device_scale_factor_ = frame.metadata.device_scale_factor;
+    display_->SetLocalSurfaceId(local_surface_id_, device_scale_factor_);
+  }
+
+  bool result =
+      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
+  DCHECK(result);
+}
+
+void DirectLayerTreeFrameSink::DidNotProduceFrame(
+    const cc::BeginFrameAck& ack) {
+  DCHECK(!ack.has_damage);
+  DCHECK_LE(cc::BeginFrameArgs::kStartingFrameNumber, ack.sequence_number);
+  support_->DidNotProduceFrame(ack);
+}
+
+void DirectLayerTreeFrameSink::DisplayOutputSurfaceLost() {
+  is_lost_ = true;
+  client_->DidLoseLayerTreeFrameSink();
+}
+
+void DirectLayerTreeFrameSink::DisplayWillDrawAndSwap(
+    bool will_draw_and_swap,
+    const cc::RenderPassList& render_passes) {
+  // This notification is not relevant to our client outside of tests.
+}
+
+void DirectLayerTreeFrameSink::DisplayDidDrawAndSwap() {
+  // This notification is not relevant to our client outside of tests. We
+  // unblock the client from DidDrawCallback() when the surface is going to
+  // be drawn.
+}
+
+void DirectLayerTreeFrameSink::DidReceiveCompositorFrameAck(
+    const std::vector<cc::ReturnedResource>& resources) {
+  client_->ReclaimResources(resources);
+  client_->DidReceiveCompositorFrameAck();
+}
+
+void DirectLayerTreeFrameSink::OnBeginFrame(const cc::BeginFrameArgs& args) {
+  begin_frame_source_->OnBeginFrame(args);
+}
+
+void DirectLayerTreeFrameSink::ReclaimResources(
+    const std::vector<cc::ReturnedResource>& resources) {
+  client_->ReclaimResources(resources);
+}
+
+void DirectLayerTreeFrameSink::WillDrawSurface(
+    const LocalSurfaceId& local_surface_id,
+    const gfx::Rect& damage_rect) {
+  // TODO(staraz): Implement this.
+}
+
+void DirectLayerTreeFrameSink::OnNeedsBeginFrames(bool needs_begin_frame) {
+  support_->SetNeedsBeginFrame(needs_begin_frame);
+}
+
+}  // namespace viz
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h
new file mode 100644
index 0000000..f8c3ee1
--- /dev/null
+++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h
@@ -0,0 +1,97 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_SERVICE_FRAME_SINKS_DIRECT_LAYER_TREE_FRAME_SINK_H_
+#define COMPONENTS_VIZ_SERVICE_FRAME_SINKS_DIRECT_LAYER_TREE_FRAME_SINK_H_
+
+#include "base/macros.h"
+#include "base/threading/thread_checker.h"
+#include "cc/output/layer_tree_frame_sink.h"
+#include "cc/scheduler/begin_frame_source.h"
+#include "components/viz/common/local_surface_id_allocator.h"
+#include "components/viz/service/display/display_client.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h"
+#include "components/viz/service/viz_service_export.h"
+
+namespace cc {
+class LocalSurfaceIdAllocator;
+class FrameSinkManager;
+}  // namespace cc
+
+namespace viz {
+class Display;
+
+// This class submits compositor frames to an in-process Display, with the
+// client's frame being the root surface of the Display.
+class VIZ_SERVICE_EXPORT DirectLayerTreeFrameSink
+    : public cc::LayerTreeFrameSink,
+      public NON_EXPORTED_BASE(CompositorFrameSinkSupportClient),
+      public cc::ExternalBeginFrameSourceClient,
+      public NON_EXPORTED_BASE(DisplayClient) {
+ public:
+  // The underlying Display, FrameSinkManager, and LocalSurfaceIdAllocator must
+  // outlive this class.
+  DirectLayerTreeFrameSink(
+      const FrameSinkId& frame_sink_id,
+      cc::FrameSinkManager* frame_sink_manager,
+      Display* display,
+      scoped_refptr<cc::ContextProvider> context_provider,
+      scoped_refptr<cc::ContextProvider> worker_context_provider,
+      gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
+      SharedBitmapManager* shared_bitmap_manager);
+  DirectLayerTreeFrameSink(
+      const FrameSinkId& frame_sink_id,
+      cc::FrameSinkManager* frame_sink_manager,
+      Display* display,
+      scoped_refptr<cc::VulkanContextProvider> vulkan_context_provider);
+  ~DirectLayerTreeFrameSink() override;
+
+  // LayerTreeFrameSink implementation.
+  bool BindToClient(cc::LayerTreeFrameSinkClient* client) override;
+  void DetachFromClient() override;
+  void SubmitCompositorFrame(cc::CompositorFrame frame) override;
+  void DidNotProduceFrame(const cc::BeginFrameAck& ack) override;
+
+  // DisplayClient implementation.
+  void DisplayOutputSurfaceLost() override;
+  void DisplayWillDrawAndSwap(bool will_draw_and_swap,
+                              const cc::RenderPassList& render_passes) override;
+  void DisplayDidDrawAndSwap() override;
+
+ protected:
+  std::unique_ptr<CompositorFrameSinkSupport> support_;  // protected for test.
+
+ private:
+  // CompositorFrameSinkSupportClient implementation:
+  void DidReceiveCompositorFrameAck(
+      const std::vector<cc::ReturnedResource>& resources) override;
+  void OnBeginFrame(const cc::BeginFrameArgs& args) override;
+  void ReclaimResources(
+      const std::vector<cc::ReturnedResource>& resources) override;
+  void WillDrawSurface(const LocalSurfaceId& local_surface_id,
+                       const gfx::Rect& damage_rect) override;
+
+  // ExternalBeginFrameSourceClient implementation:
+  void OnNeedsBeginFrames(bool needs_begin_frame) override;
+
+  // This class is only meant to be used on a single thread.
+  THREAD_CHECKER(thread_checker_);
+
+  const FrameSinkId frame_sink_id_;
+  LocalSurfaceId local_surface_id_;
+  cc::FrameSinkManager* frame_sink_manager_;
+  LocalSurfaceIdAllocator local_surface_id_allocator_;
+  Display* display_;
+  gfx::Size last_swap_frame_size_;
+  float device_scale_factor_ = 1.f;
+  bool is_lost_ = false;
+  std::unique_ptr<cc::ExternalBeginFrameSource> begin_frame_source_;
+
+  DISALLOW_COPY_AND_ASSIGN(DirectLayerTreeFrameSink);
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_SERVICE_FRAME_SINKS_DIRECT_LAYER_TREE_FRAME_SINK_H_
diff --git a/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc
new file mode 100644
index 0000000..404ff4c
--- /dev/null
+++ b/components/viz/service/frame_sinks/direct_layer_tree_frame_sink_unittest.cc
@@ -0,0 +1,151 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h"
+
+#include <memory>
+
+#include "base/memory/ptr_util.h"
+#include "cc/output/renderer_settings.h"
+#include "cc/output/texture_mailbox_deleter.h"
+#include "cc/scheduler/begin_frame_source.h"
+#include "cc/scheduler/delay_based_time_source.h"
+#include "cc/surfaces/frame_sink_manager.h"
+#include "cc/test/begin_frame_args_test.h"
+#include "cc/test/compositor_frame_helpers.h"
+#include "cc/test/fake_layer_tree_frame_sink_client.h"
+#include "cc/test/fake_output_surface.h"
+#include "cc/test/ordered_simple_task_runner.h"
+#include "cc/test/test_context_provider.h"
+#include "cc/test/test_gpu_memory_buffer_manager.h"
+#include "cc/test/test_shared_bitmap_manager.h"
+#include "components/viz/common/frame_sink_id.h"
+#include "components/viz/common/local_surface_id_allocator.h"
+#include "components/viz/service/display/display.h"
+#include "components/viz/service/display/display_scheduler.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace viz {
+namespace {
+
+static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1);
+
+class TestDirectLayerTreeFrameSink : public DirectLayerTreeFrameSink {
+ public:
+  using DirectLayerTreeFrameSink::DirectLayerTreeFrameSink;
+
+  CompositorFrameSinkSupport* support() const { return support_.get(); }
+};
+
+class DirectLayerTreeFrameSinkTest : public testing::Test {
+ public:
+  DirectLayerTreeFrameSinkTest()
+      : now_src_(new base::SimpleTestTickClock()),
+        task_runner_(new cc::OrderedSimpleTaskRunner(now_src_.get(), true)),
+        display_size_(1920, 1080),
+        display_rect_(display_size_),
+        context_provider_(cc::TestContextProvider::Create()) {
+    frame_sink_manager_.RegisterFrameSinkId(kArbitraryFrameSinkId);
+
+    auto display_output_surface = cc::FakeOutputSurface::Create3d();
+    display_output_surface_ = display_output_surface.get();
+
+    begin_frame_source_ = base::MakeUnique<cc::BackToBackBeginFrameSource>(
+        base::MakeUnique<cc::DelayBasedTimeSource>(task_runner_.get()));
+
+    int max_frames_pending = 2;
+    std::unique_ptr<DisplayScheduler> scheduler(new DisplayScheduler(
+        begin_frame_source_.get(), task_runner_.get(), max_frames_pending));
+
+    display_.reset(new Display(
+        &bitmap_manager_, &gpu_memory_buffer_manager_, cc::RendererSettings(),
+        kArbitraryFrameSinkId, std::move(display_output_surface),
+        std::move(scheduler),
+        base::MakeUnique<cc::TextureMailboxDeleter>(task_runner_.get())));
+    layer_tree_frame_sink_ = base::MakeUnique<TestDirectLayerTreeFrameSink>(
+        kArbitraryFrameSinkId, &frame_sink_manager_, display_.get(),
+        context_provider_, nullptr, &gpu_memory_buffer_manager_,
+        &bitmap_manager_);
+
+    layer_tree_frame_sink_->BindToClient(&layer_tree_frame_sink_client_);
+    display_->Resize(display_size_);
+    display_->SetVisible(true);
+
+    EXPECT_FALSE(
+        layer_tree_frame_sink_client_.did_lose_layer_tree_frame_sink_called());
+  }
+
+  ~DirectLayerTreeFrameSinkTest() override {
+    layer_tree_frame_sink_->DetachFromClient();
+  }
+
+  void SwapBuffersWithDamage(const gfx::Rect& damage_rect) {
+    auto render_pass = cc::RenderPass::Create();
+    render_pass->SetNew(1, display_rect_, damage_rect, gfx::Transform());
+
+    cc::CompositorFrame frame = cc::test::MakeEmptyCompositorFrame();
+    frame.metadata.begin_frame_ack = cc::BeginFrameAck(0, 1, 1, true);
+    frame.render_pass_list.push_back(std::move(render_pass));
+
+    layer_tree_frame_sink_->SubmitCompositorFrame(std::move(frame));
+  }
+
+  void SetUp() override {
+    // Draw the first frame to start in an "unlocked" state.
+    SwapBuffersWithDamage(display_rect_);
+
+    EXPECT_EQ(0u, display_output_surface_->num_sent_frames());
+    task_runner_->RunUntilIdle();
+    EXPECT_EQ(1u, display_output_surface_->num_sent_frames());
+  }
+
+ protected:
+  std::unique_ptr<base::SimpleTestTickClock> now_src_;
+  scoped_refptr<cc::OrderedSimpleTaskRunner> task_runner_;
+
+  const gfx::Size display_size_;
+  const gfx::Rect display_rect_;
+  cc::FrameSinkManager frame_sink_manager_;
+  cc::TestSharedBitmapManager bitmap_manager_;
+  cc::TestGpuMemoryBufferManager gpu_memory_buffer_manager_;
+
+  scoped_refptr<cc::TestContextProvider> context_provider_;
+  cc::FakeOutputSurface* display_output_surface_ = nullptr;
+  std::unique_ptr<cc::BackToBackBeginFrameSource> begin_frame_source_;
+  std::unique_ptr<Display> display_;
+  cc::FakeLayerTreeFrameSinkClient layer_tree_frame_sink_client_;
+  std::unique_ptr<TestDirectLayerTreeFrameSink> layer_tree_frame_sink_;
+};
+
+TEST_F(DirectLayerTreeFrameSinkTest, DamageTriggersSwapBuffers) {
+  SwapBuffersWithDamage(display_rect_);
+  EXPECT_EQ(1u, display_output_surface_->num_sent_frames());
+  task_runner_->RunUntilIdle();
+  EXPECT_EQ(2u, display_output_surface_->num_sent_frames());
+}
+
+TEST_F(DirectLayerTreeFrameSinkTest, NoDamageDoesNotTriggerSwapBuffers) {
+  SwapBuffersWithDamage(gfx::Rect());
+  EXPECT_EQ(1u, display_output_surface_->num_sent_frames());
+  task_runner_->RunUntilIdle();
+  EXPECT_EQ(1u, display_output_surface_->num_sent_frames());
+}
+
+TEST_F(DirectLayerTreeFrameSinkTest, SuspendedDoesNotTriggerSwapBuffers) {
+  SwapBuffersWithDamage(display_rect_);
+  EXPECT_EQ(1u, display_output_surface_->num_sent_frames());
+  display_output_surface_->set_suspended_for_recycle(true);
+  task_runner_->RunUntilIdle();
+  EXPECT_EQ(1u, display_output_surface_->num_sent_frames());
+  SwapBuffersWithDamage(display_rect_);
+  task_runner_->RunUntilIdle();
+  EXPECT_EQ(1u, display_output_surface_->num_sent_frames());
+  display_output_surface_->set_suspended_for_recycle(false);
+  SwapBuffersWithDamage(display_rect_);
+  task_runner_->RunUntilIdle();
+  EXPECT_EQ(2u, display_output_surface_->num_sent_frames());
+}
+
+}  // namespace
+}  // namespace viz
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
index a2b23eb..eca2684 100644
--- a/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
+++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.cc
@@ -10,7 +10,7 @@
 #include "base/memory/ptr_util.h"
 #include "cc/base/switches.h"
 #include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/display.h"
+#include "components/viz/service/display/display.h"
 #include "components/viz/service/display_embedder/display_provider.h"
 #include "components/viz/service/frame_sinks/gpu_compositor_frame_sink.h"
 #include "components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.h"
@@ -53,8 +53,8 @@
   DCHECK(display_provider_);
 
   std::unique_ptr<cc::BeginFrameSource> begin_frame_source;
-  std::unique_ptr<cc::Display> display = display_provider_->CreateDisplay(
-      frame_sink_id, surface_handle, &begin_frame_source);
+  auto display = display_provider_->CreateDisplay(frame_sink_id, surface_handle,
+                                                  &begin_frame_source);
 
   compositor_frame_sinks_[frame_sink_id] =
       base::MakeUnique<GpuRootCompositorFrameSink>(
diff --git a/components/viz/service/frame_sinks/frame_sink_manager_impl.h b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
index b3d3677..1d1b9f67 100644
--- a/components/viz/service/frame_sinks/frame_sink_manager_impl.h
+++ b/components/viz/service/frame_sinks/frame_sink_manager_impl.h
@@ -98,7 +98,7 @@
   // access to a valid pointer for the entirety of their lifetimes.
   cc::FrameSinkManager manager_;
 
-  // Provides a cc::Display for CreateRootCompositorFrameSink().
+  // Provides a Display for CreateRootCompositorFrameSink().
   DisplayProvider* const display_provider_;
 
   std::unordered_map<FrameSinkId,
diff --git a/components/viz/service/frame_sinks/gpu_compositor_frame_sink.cc b/components/viz/service/frame_sinks/gpu_compositor_frame_sink.cc
index 02caf452..cde9de05 100644
--- a/components/viz/service/frame_sinks/gpu_compositor_frame_sink.cc
+++ b/components/viz/service/frame_sinks/gpu_compositor_frame_sink.cc
@@ -17,7 +17,7 @@
         compositor_frame_sink_private_request,
     cc::mojom::CompositorFrameSinkClientPtr client)
     : delegate_(delegate),
-      support_(cc::CompositorFrameSinkSupport::Create(
+      support_(CompositorFrameSinkSupport::Create(
           this,
           frame_sink_manager,
           frame_sink_id,
diff --git a/components/viz/service/frame_sinks/gpu_compositor_frame_sink.h b/components/viz/service/frame_sinks/gpu_compositor_frame_sink.h
index fd22cad..8c00e84 100644
--- a/components/viz/service/frame_sinks/gpu_compositor_frame_sink.h
+++ b/components/viz/service/frame_sinks/gpu_compositor_frame_sink.h
@@ -11,10 +11,10 @@
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "cc/ipc/compositor_frame_sink.mojom.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
 #include "components/viz/common/local_surface_id.h"
 #include "components/viz/common/surface_id.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h"
 #include "components/viz/service/frame_sinks/gpu_compositor_frame_sink_delegate.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
@@ -22,7 +22,7 @@
 
 // Server side representation of a WindowSurface.
 class GpuCompositorFrameSink
-    : public NON_EXPORTED_BASE(cc::CompositorFrameSinkSupportClient),
+    : public NON_EXPORTED_BASE(CompositorFrameSinkSupportClient),
       public NON_EXPORTED_BASE(cc::mojom::CompositorFrameSink),
       public NON_EXPORTED_BASE(cc::mojom::CompositorFrameSinkPrivate) {
  public:
@@ -48,7 +48,7 @@
       std::unique_ptr<cc::CopyOutputRequest> request) override;
 
  private:
-  // cc::CompositorFrameSinkSupportClient implementation:
+  // CompositorFrameSinkSupportClient implementation:
   void DidReceiveCompositorFrameAck(
       const std::vector<cc::ReturnedResource>& resources) override;
   void OnBeginFrame(const cc::BeginFrameArgs& args) override;
@@ -61,7 +61,7 @@
   void OnPrivateConnectionLost();
 
   GpuCompositorFrameSinkDelegate* const delegate_;
-  std::unique_ptr<cc::CompositorFrameSinkSupport> support_;
+  std::unique_ptr<CompositorFrameSinkSupport> support_;
 
   cc::mojom::CompositorFrameSinkClientPtr client_;
   mojo::Binding<cc::mojom::CompositorFrameSink> compositor_frame_sink_binding_;
diff --git a/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.cc b/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.cc
index 7aa83fc3..9fb41d0 100644
--- a/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.cc
+++ b/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.cc
@@ -6,9 +6,9 @@
 
 #include <utility>
 
-#include "cc/surfaces/compositor_frame_sink_support.h"
-#include "cc/surfaces/display.h"
 #include "cc/surfaces/frame_sink_manager.h"
+#include "components/viz/service/display/display.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 
 namespace viz {
 
@@ -16,7 +16,7 @@
     GpuCompositorFrameSinkDelegate* delegate,
     cc::FrameSinkManager* frame_sink_manager,
     const FrameSinkId& frame_sink_id,
-    std::unique_ptr<cc::Display> display,
+    std::unique_ptr<Display> display,
     std::unique_ptr<cc::BeginFrameSource> begin_frame_source,
     cc::mojom::CompositorFrameSinkAssociatedRequest request,
     cc::mojom::CompositorFrameSinkPrivateRequest
@@ -24,7 +24,7 @@
     cc::mojom::CompositorFrameSinkClientPtr client,
     cc::mojom::DisplayPrivateAssociatedRequest display_private_request)
     : delegate_(delegate),
-      support_(cc::CompositorFrameSinkSupport::Create(
+      support_(CompositorFrameSinkSupport::Create(
           this,
           frame_sink_manager,
           frame_sink_id,
diff --git a/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.h b/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.h
index 584d785..e86c1f23 100644
--- a/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.h
+++ b/components/viz/service/frame_sinks/gpu_root_compositor_frame_sink.h
@@ -9,37 +9,37 @@
 
 #include "cc/ipc/compositor_frame_sink.mojom.h"
 #include "cc/ipc/frame_sink_manager.mojom.h"
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
-#include "cc/surfaces/display_client.h"
 #include "components/viz/common/local_surface_id.h"
 #include "components/viz/common/surface_id.h"
+#include "components/viz/service/display/display_client.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h"
 #include "components/viz/service/frame_sinks/gpu_compositor_frame_sink_delegate.h"
 #include "mojo/public/cpp/bindings/associated_binding.h"
 #include "mojo/public/cpp/bindings/binding.h"
 
 namespace cc {
 class BeginFrameSource;
-class CompositorFrameSinkSupport;
-class Display;
 class FrameSinkManager;
 }
 
 namespace viz {
+class CompositorFrameSinkSupport;
+class Display;
 
 class GpuCompositorFrameSinkDelegate;
 
 class GpuRootCompositorFrameSink
-    : public NON_EXPORTED_BASE(cc::CompositorFrameSinkSupportClient),
+    : public NON_EXPORTED_BASE(CompositorFrameSinkSupportClient),
       public NON_EXPORTED_BASE(cc::mojom::CompositorFrameSink),
       public NON_EXPORTED_BASE(cc::mojom::CompositorFrameSinkPrivate),
       public NON_EXPORTED_BASE(cc::mojom::DisplayPrivate),
-      public NON_EXPORTED_BASE(cc::DisplayClient) {
+      public NON_EXPORTED_BASE(DisplayClient) {
  public:
   GpuRootCompositorFrameSink(
       GpuCompositorFrameSinkDelegate* delegate,
       cc::FrameSinkManager* frame_sink_manager,
       const FrameSinkId& frame_sink_id,
-      std::unique_ptr<cc::Display> display,
+      std::unique_ptr<Display> display,
       std::unique_ptr<cc::BeginFrameSource> begin_frame_source,
       cc::mojom::CompositorFrameSinkAssociatedRequest request,
       cc::mojom::CompositorFrameSinkPrivateRequest private_request,
@@ -68,13 +68,13 @@
       std::unique_ptr<cc::CopyOutputRequest> request) override;
 
  private:
-  // cc::DisplayClient:
+  // DisplayClient:
   void DisplayOutputSurfaceLost() override;
   void DisplayWillDrawAndSwap(bool will_draw_and_swap,
                               const cc::RenderPassList& render_passes) override;
   void DisplayDidDrawAndSwap() override;
 
-  // cc::CompositorFrameSinkSupportClient:
+  // CompositorFrameSinkSupportClient:
   void DidReceiveCompositorFrameAck(
       const std::vector<cc::ReturnedResource>& resources) override;
   void OnBeginFrame(const cc::BeginFrameArgs& args) override;
@@ -87,12 +87,12 @@
   void OnPrivateConnectionLost();
 
   GpuCompositorFrameSinkDelegate* const delegate_;
-  std::unique_ptr<cc::CompositorFrameSinkSupport> support_;
+  std::unique_ptr<CompositorFrameSinkSupport> support_;
 
   // GpuRootCompositorFrameSink holds a Display and its BeginFrameSource if
   // it was created with a non-null gpu::SurfaceHandle.
   std::unique_ptr<cc::BeginFrameSource> display_begin_frame_source_;
-  std::unique_ptr<cc::Display> display_;
+  std::unique_ptr<Display> display_;
 
   cc::mojom::CompositorFrameSinkClientPtr client_;
   mojo::AssociatedBinding<cc::mojom::CompositorFrameSink>
diff --git a/components/viz/test/BUILD.gn b/components/viz/test/BUILD.gn
new file mode 100644
index 0000000..91e0425c
--- /dev/null
+++ b/components/viz/test/BUILD.gn
@@ -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.
+
+import("//components/viz/viz.gni")
+
+viz_static_library("test_support") {
+  testonly = true
+  sources = [
+    "paths.cc",
+    "paths.h",
+    "test_layer_tree_frame_sink.cc",
+    "test_layer_tree_frame_sink.h",
+  ]
+  deps = [
+    "//base",
+    "//cc",
+    "//cc/surfaces",
+    "//components/viz/service",
+    "//ui/gfx/geometry",
+  ]
+}
+
+viz_source_set("test_suite") {
+  testonly = true
+  sources = [
+    "viz_test_suite.cc",
+    "viz_test_suite.h",
+  ]
+  deps = [
+    ":test_support",
+    "//base",
+    "//base/test:test_support",
+    "//ui/gl:test_support",
+  ]
+}
diff --git a/components/viz/test/DEPS b/components/viz/test/DEPS
new file mode 100644
index 0000000..549a9a59
--- /dev/null
+++ b/components/viz/test/DEPS
@@ -0,0 +1,14 @@
+include_rules = [
+  "+cc",
+  "+ui/gfx/geometry",
+]
+
+specific_include_rules = {
+  ".*_test_suite\.cc": [
+    "+ui/gl/test",
+  ],
+
+  "run_all_unittests\.cc": [
+    "+mojo/edk/embedder/embedder.h",
+  ],
+}
diff --git a/cc/test/data/10_10_layer_tree.json b/components/viz/test/data/10_10_layer_tree.json
similarity index 100%
rename from cc/test/data/10_10_layer_tree.json
rename to components/viz/test/data/10_10_layer_tree.json
diff --git a/cc/test/data/anti_aliasing.png b/components/viz/test/data/anti_aliasing.png
similarity index 100%
rename from cc/test/data/anti_aliasing.png
rename to components/viz/test/data/anti_aliasing.png
Binary files differ
diff --git a/cc/test/data/anti_aliasing_perspective.png b/components/viz/test/data/anti_aliasing_perspective.png
similarity index 100%
rename from cc/test/data/anti_aliasing_perspective.png
rename to components/viz/test/data/anti_aliasing_perspective.png
Binary files differ
diff --git a/cc/test/data/axis_aligned.png b/components/viz/test/data/axis_aligned.png
similarity index 100%
rename from cc/test/data/axis_aligned.png
rename to components/viz/test/data/axis_aligned.png
Binary files differ
diff --git a/cc/test/data/background_filter.png b/components/viz/test/data/background_filter.png
similarity index 100%
rename from cc/test/data/background_filter.png
rename to components/viz/test/data/background_filter.png
Binary files differ
diff --git a/cc/test/data/background_filter_blur.png b/components/viz/test/data/background_filter_blur.png
similarity index 100%
rename from cc/test/data/background_filter_blur.png
rename to components/viz/test/data/background_filter_blur.png
Binary files differ
diff --git a/cc/test/data/background_filter_blur_off_axis.png b/components/viz/test/data/background_filter_blur_off_axis.png
similarity index 100%
rename from cc/test/data/background_filter_blur_off_axis.png
rename to components/viz/test/data/background_filter_blur_off_axis.png
Binary files differ
diff --git a/cc/test/data/background_filter_blur_outsets.png b/components/viz/test/data/background_filter_blur_outsets.png
similarity index 100%
rename from cc/test/data/background_filter_blur_outsets.png
rename to components/viz/test/data/background_filter_blur_outsets.png
Binary files differ
diff --git a/cc/test/data/background_filter_on_scaled_layer_gl.png b/components/viz/test/data/background_filter_on_scaled_layer_gl.png
similarity index 100%
rename from cc/test/data/background_filter_on_scaled_layer_gl.png
rename to components/viz/test/data/background_filter_on_scaled_layer_gl.png
Binary files differ
diff --git a/cc/test/data/background_filter_on_scaled_layer_sw.png b/components/viz/test/data/background_filter_on_scaled_layer_sw.png
similarity index 100%
rename from cc/test/data/background_filter_on_scaled_layer_sw.png
rename to components/viz/test/data/background_filter_on_scaled_layer_sw.png
Binary files differ
diff --git a/cc/test/data/background_filter_rotated_gl.png b/components/viz/test/data/background_filter_rotated_gl.png
similarity index 100%
rename from cc/test/data/background_filter_rotated_gl.png
rename to components/viz/test/data/background_filter_rotated_gl.png
Binary files differ
diff --git a/cc/test/data/background_filter_rotated_sw.png b/components/viz/test/data/background_filter_rotated_sw.png
similarity index 100%
rename from cc/test/data/background_filter_rotated_sw.png
rename to components/viz/test/data/background_filter_rotated_sw.png
Binary files differ
diff --git a/cc/test/data/black.png b/components/viz/test/data/black.png
similarity index 100%
rename from cc/test/data/black.png
rename to components/viz/test/data/black.png
Binary files differ
diff --git a/cc/test/data/blending_and_filter.png b/components/viz/test/data/blending_and_filter.png
similarity index 100%
rename from cc/test/data/blending_and_filter.png
rename to components/viz/test/data/blending_and_filter.png
Binary files differ
diff --git a/cc/test/data/blending_render_pass.png b/components/viz/test/data/blending_render_pass.png
similarity index 100%
rename from cc/test/data/blending_render_pass.png
rename to components/viz/test/data/blending_render_pass.png
Binary files differ
diff --git a/cc/test/data/blending_render_pass_cm.png b/components/viz/test/data/blending_render_pass_cm.png
similarity index 100%
rename from cc/test/data/blending_render_pass_cm.png
rename to components/viz/test/data/blending_render_pass_cm.png
Binary files differ
diff --git a/cc/test/data/blending_render_pass_mask.png b/components/viz/test/data/blending_render_pass_mask.png
similarity index 100%
rename from cc/test/data/blending_render_pass_mask.png
rename to components/viz/test/data/blending_render_pass_mask.png
Binary files differ
diff --git a/cc/test/data/blending_render_pass_mask_cm.png b/components/viz/test/data/blending_render_pass_mask_cm.png
similarity index 100%
rename from cc/test/data/blending_render_pass_mask_cm.png
rename to components/viz/test/data/blending_render_pass_mask_cm.png
Binary files differ
diff --git a/cc/test/data/blending_transparent.png b/components/viz/test/data/blending_transparent.png
similarity index 100%
rename from cc/test/data/blending_transparent.png
rename to components/viz/test/data/blending_transparent.png
Binary files differ
diff --git a/cc/test/data/blending_with_root.png b/components/viz/test/data/blending_with_root.png
similarity index 100%
rename from cc/test/data/blending_with_root.png
rename to components/viz/test/data/blending_with_root.png
Binary files differ
diff --git a/cc/test/data/blue_yellow.png b/components/viz/test/data/blue_yellow.png
similarity index 100%
rename from cc/test/data/blue_yellow.png
rename to components/viz/test/data/blue_yellow.png
Binary files differ
diff --git a/cc/test/data/blue_yellow_alpha.png b/components/viz/test/data/blue_yellow_alpha.png
similarity index 100%
rename from cc/test/data/blue_yellow_alpha.png
rename to components/viz/test/data/blue_yellow_alpha.png
Binary files differ
diff --git a/cc/test/data/blue_yellow_alpha_translate.png b/components/viz/test/data/blue_yellow_alpha_translate.png
similarity index 100%
rename from cc/test/data/blue_yellow_alpha_translate.png
rename to components/viz/test/data/blue_yellow_alpha_translate.png
Binary files differ
diff --git a/cc/test/data/blue_yellow_anti_aliasing.png b/components/viz/test/data/blue_yellow_anti_aliasing.png
similarity index 100%
rename from cc/test/data/blue_yellow_anti_aliasing.png
rename to components/viz/test/data/blue_yellow_anti_aliasing.png
Binary files differ
diff --git a/cc/test/data/blue_yellow_filter_chain.png b/components/viz/test/data/blue_yellow_filter_chain.png
similarity index 100%
rename from cc/test/data/blue_yellow_filter_chain.png
rename to components/viz/test/data/blue_yellow_filter_chain.png
Binary files differ
diff --git a/cc/test/data/blue_yellow_flipped.png b/components/viz/test/data/blue_yellow_flipped.png
similarity index 100%
rename from cc/test/data/blue_yellow_flipped.png
rename to components/viz/test/data/blue_yellow_flipped.png
Binary files differ
diff --git a/cc/test/data/blue_yellow_partial_flipped.png b/components/viz/test/data/blue_yellow_partial_flipped.png
similarity index 100%
rename from cc/test/data/blue_yellow_partial_flipped.png
rename to components/viz/test/data/blue_yellow_partial_flipped.png
Binary files differ
diff --git a/cc/test/data/blur_filter_with_clip_gl.png b/components/viz/test/data/blur_filter_with_clip_gl.png
similarity index 100%
rename from cc/test/data/blur_filter_with_clip_gl.png
rename to components/viz/test/data/blur_filter_with_clip_gl.png
Binary files differ
diff --git a/cc/test/data/blur_filter_with_clip_sw.png b/components/viz/test/data/blur_filter_with_clip_sw.png
similarity index 100%
rename from cc/test/data/blur_filter_with_clip_sw.png
rename to components/viz/test/data/blur_filter_with_clip_sw.png
Binary files differ
diff --git a/cc/test/data/checkers.png b/components/viz/test/data/checkers.png
similarity index 100%
rename from cc/test/data/checkers.png
rename to components/viz/test/data/checkers.png
Binary files differ
diff --git a/cc/test/data/checkers_big.png b/components/viz/test/data/checkers_big.png
similarity index 100%
rename from cc/test/data/checkers_big.png
rename to components/viz/test/data/checkers_big.png
Binary files differ
diff --git a/cc/test/data/dark_grey.png b/components/viz/test/data/dark_grey.png
similarity index 100%
rename from cc/test/data/dark_grey.png
rename to components/viz/test/data/dark_grey.png
Binary files differ
diff --git a/cc/test/data/dense_layer_tree.json b/components/viz/test/data/dense_layer_tree.json
similarity index 100%
rename from cc/test/data/dense_layer_tree.json
rename to components/viz/test/data/dense_layer_tree.json
diff --git a/cc/test/data/enlarged_texture_on_crop_offset.png b/components/viz/test/data/enlarged_texture_on_crop_offset.png
similarity index 100%
rename from cc/test/data/enlarged_texture_on_crop_offset.png
rename to components/viz/test/data/enlarged_texture_on_crop_offset.png
Binary files differ
diff --git a/cc/test/data/enlarged_texture_on_threshold.png b/components/viz/test/data/enlarged_texture_on_threshold.png
similarity index 100%
rename from cc/test/data/enlarged_texture_on_threshold.png
rename to components/viz/test/data/enlarged_texture_on_threshold.png
Binary files differ
diff --git a/cc/test/data/filter_with_giant_crop_rect.png b/components/viz/test/data/filter_with_giant_crop_rect.png
similarity index 100%
rename from cc/test/data/filter_with_giant_crop_rect.png
rename to components/viz/test/data/filter_with_giant_crop_rect.png
Binary files differ
diff --git a/cc/test/data/force_anti_aliasing_off.png b/components/viz/test/data/force_anti_aliasing_off.png
similarity index 100%
rename from cc/test/data/force_anti_aliasing_off.png
rename to components/viz/test/data/force_anti_aliasing_off.png
Binary files differ
diff --git a/cc/test/data/four_blue_green_checkers.png b/components/viz/test/data/four_blue_green_checkers.png
similarity index 100%
rename from cc/test/data/four_blue_green_checkers.png
rename to components/viz/test/data/four_blue_green_checkers.png
Binary files differ
diff --git a/cc/test/data/four_blue_green_checkers_linear.png b/components/viz/test/data/four_blue_green_checkers_linear.png
similarity index 100%
rename from cc/test/data/four_blue_green_checkers_linear.png
rename to components/viz/test/data/four_blue_green_checkers_linear.png
Binary files differ
diff --git a/cc/test/data/green.png b/components/viz/test/data/green.png
similarity index 100%
rename from cc/test/data/green.png
rename to components/viz/test/data/green.png
Binary files differ
diff --git a/cc/test/data/green_alpha.png b/components/viz/test/data/green_alpha.png
similarity index 100%
rename from cc/test/data/green_alpha.png
rename to components/viz/test/data/green_alpha.png
Binary files differ
diff --git a/cc/test/data/green_alpha_vertex_opacity.png b/components/viz/test/data/green_alpha_vertex_opacity.png
similarity index 100%
rename from cc/test/data/green_alpha_vertex_opacity.png
rename to components/viz/test/data/green_alpha_vertex_opacity.png
Binary files differ
diff --git a/cc/test/data/green_small.png b/components/viz/test/data/green_small.png
similarity index 100%
rename from cc/test/data/green_small.png
rename to components/viz/test/data/green_small.png
Binary files differ
diff --git a/cc/test/data/green_small_with_blue_corner.png b/components/viz/test/data/green_small_with_blue_corner.png
similarity index 100%
rename from cc/test/data/green_small_with_blue_corner.png
rename to components/viz/test/data/green_small_with_blue_corner.png
Binary files differ
diff --git a/cc/test/data/green_with_blue_corner.png b/components/viz/test/data/green_with_blue_corner.png
similarity index 100%
rename from cc/test/data/green_with_blue_corner.png
rename to components/viz/test/data/green_with_blue_corner.png
Binary files differ
diff --git a/cc/test/data/heavy_layer_tree.json b/components/viz/test/data/heavy_layer_tree.json
similarity index 100%
rename from cc/test/data/heavy_layer_tree.json
rename to components/viz/test/data/heavy_layer_tree.json
diff --git a/cc/test/data/image_mask_of_layer.png b/components/viz/test/data/image_mask_of_layer.png
similarity index 100%
rename from cc/test/data/image_mask_of_layer.png
rename to components/viz/test/data/image_mask_of_layer.png
Binary files differ
diff --git a/cc/test/data/intersecting_blue_green.png b/components/viz/test/data/intersecting_blue_green.png
similarity index 100%
rename from cc/test/data/intersecting_blue_green.png
rename to components/viz/test/data/intersecting_blue_green.png
Binary files differ
diff --git a/cc/test/data/intersecting_blue_green_squares.png b/components/viz/test/data/intersecting_blue_green_squares.png
similarity index 100%
rename from cc/test/data/intersecting_blue_green_squares.png
rename to components/viz/test/data/intersecting_blue_green_squares.png
Binary files differ
diff --git a/cc/test/data/intersecting_blue_green_squares_video.png b/components/viz/test/data/intersecting_blue_green_squares_video.png
similarity index 100%
rename from cc/test/data/intersecting_blue_green_squares_video.png
rename to components/viz/test/data/intersecting_blue_green_squares_video.png
Binary files differ
diff --git a/cc/test/data/intersecting_light_dark_squares_video.png b/components/viz/test/data/intersecting_light_dark_squares_video.png
similarity index 100%
rename from cc/test/data/intersecting_light_dark_squares_video.png
rename to components/viz/test/data/intersecting_light_dark_squares_video.png
Binary files differ
diff --git a/cc/test/data/layer_sort_cubes.json b/components/viz/test/data/layer_sort_cubes.json
similarity index 100%
rename from cc/test/data/layer_sort_cubes.json
rename to components/viz/test/data/layer_sort_cubes.json
diff --git a/cc/test/data/layer_sort_rubik.json b/components/viz/test/data/layer_sort_rubik.json
similarity index 100%
rename from cc/test/data/layer_sort_rubik.json
rename to components/viz/test/data/layer_sort_rubik.json
diff --git a/cc/test/data/long_scrollable_page.json b/components/viz/test/data/long_scrollable_page.json
similarity index 100%
rename from cc/test/data/long_scrollable_page.json
rename to components/viz/test/data/long_scrollable_page.json
diff --git a/cc/test/data/mask_bottom_right.png b/components/viz/test/data/mask_bottom_right.png
similarity index 100%
rename from cc/test/data/mask_bottom_right.png
rename to components/viz/test/data/mask_bottom_right.png
Binary files differ
diff --git a/cc/test/data/mask_middle.png b/components/viz/test/data/mask_middle.png
similarity index 100%
rename from cc/test/data/mask_middle.png
rename to components/viz/test/data/mask_middle.png
Binary files differ
diff --git a/cc/test/data/mask_of_background_filter.png b/components/viz/test/data/mask_of_background_filter.png
similarity index 100%
rename from cc/test/data/mask_of_background_filter.png
rename to components/viz/test/data/mask_of_background_filter.png
Binary files differ
diff --git a/cc/test/data/mask_of_clipped_layer.png b/components/viz/test/data/mask_of_clipped_layer.png
similarity index 100%
rename from cc/test/data/mask_of_clipped_layer.png
rename to components/viz/test/data/mask_of_clipped_layer.png
Binary files differ
diff --git a/cc/test/data/mask_of_layer.png b/components/viz/test/data/mask_of_layer.png
similarity index 100%
rename from cc/test/data/mask_of_layer.png
rename to components/viz/test/data/mask_of_layer.png
Binary files differ
diff --git a/cc/test/data/mask_of_layer_with_blend.png b/components/viz/test/data/mask_of_layer_with_blend.png
similarity index 100%
rename from cc/test/data/mask_of_layer_with_blend.png
rename to components/viz/test/data/mask_of_layer_with_blend.png
Binary files differ
diff --git a/cc/test/data/mask_of_replica.png b/components/viz/test/data/mask_of_replica.png
similarity index 100%
rename from cc/test/data/mask_of_replica.png
rename to components/viz/test/data/mask_of_replica.png
Binary files differ
diff --git a/cc/test/data/mask_of_replica_of_clipped_layer.png b/components/viz/test/data/mask_of_replica_of_clipped_layer.png
similarity index 100%
rename from cc/test/data/mask_of_replica_of_clipped_layer.png
rename to components/viz/test/data/mask_of_replica_of_clipped_layer.png
Binary files differ
diff --git a/cc/test/data/mask_with_non_exact_texture_size.png b/components/viz/test/data/mask_with_non_exact_texture_size.png
similarity index 100%
rename from cc/test/data/mask_with_non_exact_texture_size.png
rename to components/viz/test/data/mask_with_non_exact_texture_size.png
Binary files differ
diff --git a/cc/test/data/mask_with_replica.png b/components/viz/test/data/mask_with_replica.png
similarity index 100%
rename from cc/test/data/mask_with_replica.png
rename to components/viz/test/data/mask_with_replica.png
Binary files differ
diff --git a/cc/test/data/mask_with_replica_of_clipped_layer.png b/components/viz/test/data/mask_with_replica_of_clipped_layer.png
similarity index 100%
rename from cc/test/data/mask_with_replica_of_clipped_layer.png
rename to components/viz/test/data/mask_with_replica_of_clipped_layer.png
Binary files differ
diff --git a/cc/test/data/offset_background_filter_1x.png b/components/viz/test/data/offset_background_filter_1x.png
similarity index 100%
rename from cc/test/data/offset_background_filter_1x.png
rename to components/viz/test/data/offset_background_filter_1x.png
Binary files differ
diff --git a/cc/test/data/offset_background_filter_2x.png b/components/viz/test/data/offset_background_filter_2x.png
similarity index 100%
rename from cc/test/data/offset_background_filter_2x.png
rename to components/viz/test/data/offset_background_filter_2x.png
Binary files differ
diff --git a/cc/test/data/overlay_scrollbar_scaled_down.png b/components/viz/test/data/overlay_scrollbar_scaled_down.png
similarity index 100%
rename from cc/test/data/overlay_scrollbar_scaled_down.png
rename to components/viz/test/data/overlay_scrollbar_scaled_down.png
Binary files differ
diff --git a/cc/test/data/overlay_scrollbar_scaled_up.png b/components/viz/test/data/overlay_scrollbar_scaled_up.png
similarity index 100%
rename from cc/test/data/overlay_scrollbar_scaled_up.png
rename to components/viz/test/data/overlay_scrollbar_scaled_up.png
Binary files differ
diff --git a/cc/test/data/rotated_drop_shadow_filter_gl.png b/components/viz/test/data/rotated_drop_shadow_filter_gl.png
similarity index 100%
rename from cc/test/data/rotated_drop_shadow_filter_gl.png
rename to components/viz/test/data/rotated_drop_shadow_filter_gl.png
Binary files differ
diff --git a/cc/test/data/rotated_drop_shadow_filter_sw.png b/components/viz/test/data/rotated_drop_shadow_filter_sw.png
similarity index 100%
rename from cc/test/data/rotated_drop_shadow_filter_sw.png
rename to components/viz/test/data/rotated_drop_shadow_filter_sw.png
Binary files differ
diff --git a/cc/test/data/rotated_filter_gl.png b/components/viz/test/data/rotated_filter_gl.png
similarity index 100%
rename from cc/test/data/rotated_filter_gl.png
rename to components/viz/test/data/rotated_filter_gl.png
Binary files differ
diff --git a/cc/test/data/rotated_filter_sw.png b/components/viz/test/data/rotated_filter_sw.png
similarity index 100%
rename from cc/test/data/rotated_filter_sw.png
rename to components/viz/test/data/rotated_filter_sw.png
Binary files differ
diff --git a/cc/test/data/scaled_render_surface_layer_gl.png b/components/viz/test/data/scaled_render_surface_layer_gl.png
similarity index 100%
rename from cc/test/data/scaled_render_surface_layer_gl.png
rename to components/viz/test/data/scaled_render_surface_layer_gl.png
Binary files differ
diff --git a/cc/test/data/scaled_render_surface_layer_sw.png b/components/viz/test/data/scaled_render_surface_layer_sw.png
similarity index 100%
rename from cc/test/data/scaled_render_surface_layer_sw.png
rename to components/viz/test/data/scaled_render_surface_layer_sw.png
Binary files differ
diff --git a/cc/test/data/spiral.png b/components/viz/test/data/spiral.png
similarity index 100%
rename from cc/test/data/spiral.png
rename to components/viz/test/data/spiral.png
Binary files differ
diff --git a/cc/test/data/spiral_64_scale.png b/components/viz/test/data/spiral_64_scale.png
similarity index 100%
rename from cc/test/data/spiral_64_scale.png
rename to components/viz/test/data/spiral_64_scale.png
Binary files differ
diff --git a/cc/test/data/spiral_double_scale.png b/components/viz/test/data/spiral_double_scale.png
similarity index 100%
rename from cc/test/data/spiral_double_scale.png
rename to components/viz/test/data/spiral_double_scale.png
Binary files differ
diff --git a/cc/test/data/touch_region_heavy.json b/components/viz/test/data/touch_region_heavy.json
similarity index 100%
rename from cc/test/data/touch_region_heavy.json
rename to components/viz/test/data/touch_region_heavy.json
diff --git a/cc/test/data/touch_region_light.json b/components/viz/test/data/touch_region_light.json
similarity index 100%
rename from cc/test/data/touch_region_light.json
rename to components/viz/test/data/touch_region_light.json
diff --git a/cc/test/data/translated_blue_green_alpha_gl.png b/components/viz/test/data/translated_blue_green_alpha_gl.png
similarity index 100%
rename from cc/test/data/translated_blue_green_alpha_gl.png
rename to components/viz/test/data/translated_blue_green_alpha_gl.png
Binary files differ
diff --git a/cc/test/data/translated_blue_green_alpha_sw.png b/components/viz/test/data/translated_blue_green_alpha_sw.png
similarity index 100%
rename from cc/test/data/translated_blue_green_alpha_sw.png
rename to components/viz/test/data/translated_blue_green_alpha_sw.png
Binary files differ
diff --git a/cc/test/data/translucent_rectangles.png b/components/viz/test/data/translucent_rectangles.png
similarity index 100%
rename from cc/test/data/translucent_rectangles.png
rename to components/viz/test/data/translucent_rectangles.png
Binary files differ
diff --git a/cc/test/data/white.png b/components/viz/test/data/white.png
similarity index 100%
rename from cc/test/data/white.png
rename to components/viz/test/data/white.png
Binary files differ
diff --git a/cc/test/data/wrap_mode_repeat.png b/components/viz/test/data/wrap_mode_repeat.png
similarity index 100%
rename from cc/test/data/wrap_mode_repeat.png
rename to components/viz/test/data/wrap_mode_repeat.png
Binary files differ
diff --git a/cc/test/data/yuv_stripes.png b/components/viz/test/data/yuv_stripes.png
similarity index 100%
rename from cc/test/data/yuv_stripes.png
rename to components/viz/test/data/yuv_stripes.png
Binary files differ
diff --git a/cc/test/data/yuv_stripes_alpha.png b/components/viz/test/data/yuv_stripes_alpha.png
similarity index 100%
rename from cc/test/data/yuv_stripes_alpha.png
rename to components/viz/test/data/yuv_stripes_alpha.png
Binary files differ
diff --git a/cc/test/data/yuv_stripes_clipped.png b/components/viz/test/data/yuv_stripes_clipped.png
similarity index 100%
rename from cc/test/data/yuv_stripes_clipped.png
rename to components/viz/test/data/yuv_stripes_clipped.png
Binary files differ
diff --git a/cc/test/data/yuv_stripes_offset.png b/components/viz/test/data/yuv_stripes_offset.png
similarity index 100%
rename from cc/test/data/yuv_stripes_offset.png
rename to components/viz/test/data/yuv_stripes_offset.png
Binary files differ
diff --git a/cc/test/data/zoom_filter_gl.png b/components/viz/test/data/zoom_filter_gl.png
similarity index 100%
rename from cc/test/data/zoom_filter_gl.png
rename to components/viz/test/data/zoom_filter_gl.png
Binary files differ
diff --git a/cc/test/data/zoom_filter_sw.png b/components/viz/test/data/zoom_filter_sw.png
similarity index 100%
rename from cc/test/data/zoom_filter_sw.png
rename to components/viz/test/data/zoom_filter_sw.png
Binary files differ
diff --git a/components/viz/test/paths.cc b/components/viz/test/paths.cc
new file mode 100644
index 0000000..998e5c4
--- /dev/null
+++ b/components/viz/test/paths.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 "components/viz/test/paths.h"
+
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/path_service.h"
+
+namespace viz {
+
+bool PathProvider(int key, base::FilePath* result) {
+  base::FilePath cur;
+  switch (key) {
+    // The following are only valid in the development environment, and
+    // will fail if executed from an installed executable (because the
+    // generated path won't exist).
+    case Paths::DIR_TEST_DATA:
+      if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur))
+        return false;
+      cur = cur.Append(FILE_PATH_LITERAL("components"));
+      cur = cur.Append(FILE_PATH_LITERAL("viz"));
+      cur = cur.Append(FILE_PATH_LITERAL("test"));
+      cur = cur.Append(FILE_PATH_LITERAL("data"));
+      if (!base::PathExists(cur))  // we don't want to create this
+        return false;
+      break;
+    default:
+      return false;
+  }
+
+  *result = cur;
+  return true;
+}
+
+// This cannot be done as a static initializer sadly since Visual Studio will
+// eliminate this object file if there is no direct entry point into it.
+void Paths::RegisterPathProvider() {
+  PathService::RegisterProvider(PathProvider, PATH_START, PATH_END);
+}
+
+}  // namespace viz
diff --git a/components/viz/test/paths.h b/components/viz/test/paths.h
new file mode 100644
index 0000000..f5533a1f
--- /dev/null
+++ b/components/viz/test/paths.h
@@ -0,0 +1,26 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_VIZ_TEST_PATHS_H_
+#define COMPONENTS_VIZ_TEST_PATHS_H_
+
+namespace viz {
+
+class Paths {
+ public:
+  enum {
+    PATH_START = 5000,
+
+    // Valid only in development and testing environments.
+    DIR_TEST_DATA,
+    PATH_END
+  };
+
+  // Call once to register the provider for the path keys defined above.
+  static void RegisterPathProvider();
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_TEST_PATHS_H_
diff --git a/components/viz/test/run_all_perftests.cc b/components/viz/test/run_all_perftests.cc
new file mode 100644
index 0000000..8f0aae4
--- /dev/null
+++ b/components/viz/test/run_all_perftests.cc
@@ -0,0 +1,18 @@
+// 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 "base/bind.h"
+#include "base/test/launcher/unit_test_launcher.h"
+#include "components/viz/test/viz_test_suite.h"
+
+int main(int argc, char** argv) {
+  viz::VizTestSuite test_suite(argc, argv);
+
+  // Always run the perf tests serially, to avoid distorting
+  // perf measurements with randomness resulting from running
+  // in parallel.
+  return base::LaunchUnitTestsSerially(
+      argc, argv,
+      base::Bind(&viz::VizTestSuite::Run, base::Unretained(&test_suite)));
+}
diff --git a/components/viz/test/run_all_unittests.cc b/components/viz/test/run_all_unittests.cc
new file mode 100644
index 0000000..de93e66
--- /dev/null
+++ b/components/viz/test/run_all_unittests.cc
@@ -0,0 +1,18 @@
+// 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 "base/bind.h"
+#include "base/test/launcher/unit_test_launcher.h"
+#include "components/viz/test/viz_test_suite.h"
+#include "mojo/edk/embedder/embedder.h"
+
+int main(int argc, char** argv) {
+  viz::VizTestSuite test_suite(argc, argv);
+
+  mojo::edk::Init();
+
+  return base::LaunchUnitTests(
+      argc, argv,
+      base::Bind(&viz::VizTestSuite::Run, base::Unretained(&test_suite)));
+}
diff --git a/components/viz/test/test_layer_tree_frame_sink.cc b/components/viz/test/test_layer_tree_frame_sink.cc
new file mode 100644
index 0000000..3c1f2f6
--- /dev/null
+++ b/components/viz/test/test_layer_tree_frame_sink.cc
@@ -0,0 +1,222 @@
+// 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 "components/viz/test/test_layer_tree_frame_sink.h"
+
+#include <stdint.h>
+#include <utility>
+
+#include "base/memory/ptr_util.h"
+#include "base/single_thread_task_runner.h"
+#include "cc/output/begin_frame_args.h"
+#include "cc/output/copy_output_request.h"
+#include "cc/output/direct_renderer.h"
+#include "cc/output/layer_tree_frame_sink_client.h"
+#include "cc/output/output_surface.h"
+#include "cc/output/texture_mailbox_deleter.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
+
+namespace viz {
+
+static constexpr FrameSinkId kLayerTreeFrameSinkId(1, 1);
+
+TestLayerTreeFrameSink::TestLayerTreeFrameSink(
+    scoped_refptr<cc::ContextProvider> compositor_context_provider,
+    scoped_refptr<cc::ContextProvider> worker_context_provider,
+    SharedBitmapManager* shared_bitmap_manager,
+    gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
+    const cc::RendererSettings& renderer_settings,
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+    bool synchronous_composite,
+    bool disable_display_vsync,
+    double refresh_rate)
+    : LayerTreeFrameSink(std::move(compositor_context_provider),
+                         std::move(worker_context_provider),
+                         gpu_memory_buffer_manager,
+                         shared_bitmap_manager),
+      synchronous_composite_(synchronous_composite),
+      disable_display_vsync_(disable_display_vsync),
+      renderer_settings_(renderer_settings),
+      refresh_rate_(refresh_rate),
+      task_runner_(std::move(task_runner)),
+      frame_sink_id_(kLayerTreeFrameSinkId),
+      frame_sink_manager_(new cc::FrameSinkManager),
+      local_surface_id_allocator_(new LocalSurfaceIdAllocator),
+      external_begin_frame_source_(this),
+      weak_ptr_factory_(this) {
+  // Always use sync tokens so that code paths in resource provider that deal
+  // with sync tokens are tested.
+  capabilities_.delegated_sync_points_required = true;
+}
+
+TestLayerTreeFrameSink::~TestLayerTreeFrameSink() {
+  DCHECK(copy_requests_.empty());
+}
+
+void TestLayerTreeFrameSink::RequestCopyOfOutput(
+    std::unique_ptr<cc::CopyOutputRequest> request) {
+  copy_requests_.push_back(std::move(request));
+}
+
+bool TestLayerTreeFrameSink::BindToClient(
+    cc::LayerTreeFrameSinkClient* client) {
+  if (!LayerTreeFrameSink::BindToClient(client))
+    return false;
+
+  std::unique_ptr<cc::OutputSurface> display_output_surface =
+      test_client_->CreateDisplayOutputSurface(context_provider());
+  bool display_context_shared_with_compositor =
+      display_output_surface->context_provider() == context_provider();
+
+  std::unique_ptr<DisplayScheduler> scheduler;
+  if (!synchronous_composite_) {
+    if (disable_display_vsync_) {
+      begin_frame_source_ = base::MakeUnique<cc::BackToBackBeginFrameSource>(
+          base::MakeUnique<cc::DelayBasedTimeSource>(task_runner_.get()));
+    } else {
+      begin_frame_source_ = base::MakeUnique<cc::DelayBasedBeginFrameSource>(
+          base::MakeUnique<cc::DelayBasedTimeSource>(task_runner_.get()));
+      begin_frame_source_->SetAuthoritativeVSyncInterval(
+          base::TimeDelta::FromMilliseconds(1000.f / refresh_rate_));
+    }
+    scheduler = base::MakeUnique<DisplayScheduler>(
+        begin_frame_source_.get(), task_runner_.get(),
+        display_output_surface->capabilities().max_frames_pending);
+  }
+
+  display_ = base::MakeUnique<Display>(
+      shared_bitmap_manager(), gpu_memory_buffer_manager(), renderer_settings_,
+      frame_sink_id_, std::move(display_output_surface), std::move(scheduler),
+      base::MakeUnique<cc::TextureMailboxDeleter>(task_runner_.get()));
+
+  // We want the Display's OutputSurface to hear about lost context, and when
+  // this shares a context with it we should not be listening for lost context
+  // callbacks on the context here.
+  if (display_context_shared_with_compositor && context_provider())
+    context_provider()->SetLostContextCallback(base::Closure());
+
+  constexpr bool is_root = false;
+  constexpr bool handles_frame_sink_id_invalidation = true;
+  constexpr bool needs_sync_points = true;
+  support_ = CompositorFrameSinkSupport::Create(
+      this, frame_sink_manager_.get(), frame_sink_id_, is_root,
+      handles_frame_sink_id_invalidation, needs_sync_points);
+  client_->SetBeginFrameSource(&external_begin_frame_source_);
+  if (begin_frame_source_) {
+    frame_sink_manager_->RegisterBeginFrameSource(begin_frame_source_.get(),
+                                                  frame_sink_id_);
+  }
+  display_->Initialize(this, frame_sink_manager_->surface_manager());
+  display_->renderer_for_testing()->SetEnlargePassTextureAmountForTesting(
+      enlarge_pass_texture_amount_);
+  display_->SetVisible(true);
+  return true;
+}
+
+void TestLayerTreeFrameSink::DetachFromClient() {
+  if (begin_frame_source_)
+    frame_sink_manager_->UnregisterBeginFrameSource(begin_frame_source_.get());
+  client_->SetBeginFrameSource(nullptr);
+  support_ = nullptr;
+  display_ = nullptr;
+  begin_frame_source_ = nullptr;
+  local_surface_id_allocator_ = nullptr;
+  frame_sink_manager_ = nullptr;
+  test_client_ = nullptr;
+  LayerTreeFrameSink::DetachFromClient();
+}
+
+void TestLayerTreeFrameSink::SetLocalSurfaceId(
+    const LocalSurfaceId& local_surface_id) {
+  test_client_->DisplayReceivedLocalSurfaceId(local_surface_id);
+}
+
+void TestLayerTreeFrameSink::SubmitCompositorFrame(cc::CompositorFrame frame) {
+  DCHECK(frame.metadata.begin_frame_ack.has_damage);
+  DCHECK_LE(cc::BeginFrameArgs::kStartingFrameNumber,
+            frame.metadata.begin_frame_ack.sequence_number);
+  test_client_->DisplayReceivedCompositorFrame(frame);
+
+  gfx::Size frame_size = frame.render_pass_list.back()->output_rect.size();
+  float device_scale_factor = frame.metadata.device_scale_factor;
+  if (!local_surface_id_.is_valid() || frame_size != display_size_ ||
+      device_scale_factor != device_scale_factor_) {
+    local_surface_id_ = local_surface_id_allocator_->GenerateId();
+    display_->SetLocalSurfaceId(local_surface_id_, device_scale_factor);
+    display_->Resize(frame_size);
+    display_size_ = frame_size;
+    device_scale_factor_ = device_scale_factor;
+  }
+
+  bool result =
+      support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
+  DCHECK(result);
+
+  for (auto& copy_request : copy_requests_)
+    support_->RequestCopyOfSurface(std::move(copy_request));
+  copy_requests_.clear();
+
+  if (!display_->has_scheduler()) {
+    display_->DrawAndSwap();
+    // Post this to get a new stack frame so that we exit this function before
+    // calling the client to tell it that it is done.
+    task_runner_->PostTask(
+        FROM_HERE,
+        base::BindOnce(&TestLayerTreeFrameSink::SendCompositorFrameAckToClient,
+                       weak_ptr_factory_.GetWeakPtr()));
+  }
+}
+
+void TestLayerTreeFrameSink::DidNotProduceFrame(const cc::BeginFrameAck& ack) {
+  DCHECK(!ack.has_damage);
+  DCHECK_LE(cc::BeginFrameArgs::kStartingFrameNumber, ack.sequence_number);
+  support_->DidNotProduceFrame(ack);
+}
+
+void TestLayerTreeFrameSink::DidReceiveCompositorFrameAck(
+    const std::vector<cc::ReturnedResource>& resources) {
+  ReclaimResources(resources);
+  // In synchronous mode, we manually send acks and this method should not be
+  // used.
+  if (!display_->has_scheduler())
+    return;
+  client_->DidReceiveCompositorFrameAck();
+}
+
+void TestLayerTreeFrameSink::OnBeginFrame(const cc::BeginFrameArgs& args) {
+  external_begin_frame_source_.OnBeginFrame(args);
+}
+
+void TestLayerTreeFrameSink::ReclaimResources(
+    const std::vector<cc::ReturnedResource>& resources) {
+  client_->ReclaimResources(resources);
+}
+
+void TestLayerTreeFrameSink::WillDrawSurface(
+    const LocalSurfaceId& local_surface_id,
+    const gfx::Rect& damage_rect) {}
+
+void TestLayerTreeFrameSink::DisplayOutputSurfaceLost() {
+  client_->DidLoseLayerTreeFrameSink();
+}
+
+void TestLayerTreeFrameSink::DisplayWillDrawAndSwap(
+    bool will_draw_and_swap,
+    const cc::RenderPassList& render_passes) {
+  test_client_->DisplayWillDrawAndSwap(will_draw_and_swap, render_passes);
+}
+
+void TestLayerTreeFrameSink::DisplayDidDrawAndSwap() {
+  test_client_->DisplayDidDrawAndSwap();
+}
+
+void TestLayerTreeFrameSink::OnNeedsBeginFrames(bool needs_begin_frames) {
+  support_->SetNeedsBeginFrame(needs_begin_frames);
+}
+
+void TestLayerTreeFrameSink::SendCompositorFrameAckToClient() {
+  client_->DidReceiveCompositorFrameAck();
+}
+
+}  // namespace viz
diff --git a/components/viz/test/test_layer_tree_frame_sink.h b/components/viz/test/test_layer_tree_frame_sink.h
new file mode 100644
index 0000000..e155acb
--- /dev/null
+++ b/components/viz/test/test_layer_tree_frame_sink.h
@@ -0,0 +1,146 @@
+// 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 COMPONENTS_VIZ_TEST_TEST_LAYER_TREE_FRAME_SINK_H_
+#define COMPONENTS_VIZ_TEST_TEST_LAYER_TREE_FRAME_SINK_H_
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "cc/output/layer_tree_frame_sink.h"
+#include "cc/output/renderer_settings.h"
+#include "cc/scheduler/begin_frame_source.h"
+#include "cc/surfaces/frame_sink_manager.h"
+#include "components/viz/common/local_surface_id_allocator.h"
+#include "components/viz/service/display/display.h"
+#include "components/viz/service/display/display_client.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h"
+
+namespace base {
+class SingleThreadTaskRunner;
+}
+
+namespace cc {
+class CopyOutputRequest;
+class OutputSurface;
+}  // namespace cc
+
+namespace viz {
+class CompositorFrameSinkSupport;
+
+class TestLayerTreeFrameSinkClient {
+ public:
+  virtual ~TestLayerTreeFrameSinkClient() {}
+
+  // This passes the ContextProvider being used by LayerTreeHostImpl which
+  // can be used for the OutputSurface optionally.
+  virtual std::unique_ptr<cc::OutputSurface> CreateDisplayOutputSurface(
+      scoped_refptr<cc::ContextProvider> compositor_context_provider) = 0;
+
+  virtual void DisplayReceivedLocalSurfaceId(
+      const LocalSurfaceId& local_surface_id) = 0;
+  virtual void DisplayReceivedCompositorFrame(
+      const cc::CompositorFrame& frame) = 0;
+  virtual void DisplayWillDrawAndSwap(
+      bool will_draw_and_swap,
+      const cc::RenderPassList& render_passes) = 0;
+  virtual void DisplayDidDrawAndSwap() = 0;
+};
+
+// LayerTreeFrameSink that owns and forwards frames to a Display.
+class TestLayerTreeFrameSink : public cc::LayerTreeFrameSink,
+                               public CompositorFrameSinkSupportClient,
+                               public DisplayClient,
+                               public cc::ExternalBeginFrameSourceClient {
+ public:
+  // Pass true for |force_disable_reclaim_resources| to act like the Display
+  // is out-of-process and can't return resources synchronously.
+  TestLayerTreeFrameSink(
+      scoped_refptr<cc::ContextProvider> compositor_context_provider,
+      scoped_refptr<cc::ContextProvider> worker_context_provider,
+      SharedBitmapManager* shared_bitmap_manager,
+      gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager,
+      const cc::RendererSettings& renderer_settings,
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
+      bool synchronous_composite,
+      bool disable_display_vsync,
+      double refresh_rate);
+  ~TestLayerTreeFrameSink() override;
+
+  // This client must be set before BindToClient() happens.
+  void SetClient(TestLayerTreeFrameSinkClient* client) {
+    test_client_ = client;
+  }
+  void SetEnlargePassTextureAmount(const gfx::Size& s) {
+    enlarge_pass_texture_amount_ = s;
+  }
+
+  Display* display() const { return display_.get(); }
+
+  // Will be included with the next SubmitCompositorFrame.
+  void RequestCopyOfOutput(std::unique_ptr<cc::CopyOutputRequest> request);
+
+  // LayerTreeFrameSink implementation.
+  bool BindToClient(cc::LayerTreeFrameSinkClient* client) override;
+  void DetachFromClient() override;
+  void SetLocalSurfaceId(const LocalSurfaceId& local_surface_id) override;
+  void SubmitCompositorFrame(cc::CompositorFrame frame) override;
+  void DidNotProduceFrame(const cc::BeginFrameAck& ack) override;
+
+  // CompositorFrameSinkSupportClient implementation.
+  void DidReceiveCompositorFrameAck(
+      const std::vector<cc::ReturnedResource>& resources) override;
+  void OnBeginFrame(const cc::BeginFrameArgs& args) override;
+  void ReclaimResources(
+      const std::vector<cc::ReturnedResource>& resources) override;
+  void WillDrawSurface(const LocalSurfaceId& local_surface_id,
+                       const gfx::Rect& damage_rect) override;
+
+  // DisplayClient implementation.
+  void DisplayOutputSurfaceLost() override;
+  void DisplayWillDrawAndSwap(bool will_draw_and_swap,
+                              const cc::RenderPassList& render_passes) override;
+  void DisplayDidDrawAndSwap() override;
+
+ private:
+  // ExternalBeginFrameSource implementation.
+  void OnNeedsBeginFrames(bool needs_begin_frames) override;
+
+  void SendCompositorFrameAckToClient();
+
+  const bool synchronous_composite_;
+  const bool disable_display_vsync_;
+  const cc::RendererSettings renderer_settings_;
+  const double refresh_rate_;
+
+  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
+
+  FrameSinkId frame_sink_id_;
+  // TODO(danakj): These don't need to be stored in unique_ptrs when
+  // LayerTreeFrameSink is owned/destroyed on the compositor thread.
+  std::unique_ptr<cc::FrameSinkManager> frame_sink_manager_;
+  std::unique_ptr<LocalSurfaceIdAllocator> local_surface_id_allocator_;
+  LocalSurfaceId local_surface_id_;
+  gfx::Size display_size_;
+  float device_scale_factor_ = 0;
+
+  // Uses surface_manager_.
+  std::unique_ptr<CompositorFrameSinkSupport> support_;
+
+  std::unique_ptr<cc::SyntheticBeginFrameSource> begin_frame_source_;
+  cc::ExternalBeginFrameSource external_begin_frame_source_;
+
+  // Uses surface_manager_ and begin_frame_source_.
+  std::unique_ptr<Display> display_;
+
+  TestLayerTreeFrameSinkClient* test_client_ = nullptr;
+  gfx::Size enlarge_pass_texture_amount_;
+
+  std::vector<std::unique_ptr<cc::CopyOutputRequest>> copy_requests_;
+
+  base::WeakPtrFactory<TestLayerTreeFrameSink> weak_ptr_factory_;
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_TEST_TEST_LAYER_TREE_FRAME_SINK_H_
diff --git a/components/viz/test/viz_test_suite.cc b/components/viz/test/viz_test_suite.cc
new file mode 100644
index 0000000..f72dcb2b
--- /dev/null
+++ b/components/viz/test/viz_test_suite.cc
@@ -0,0 +1,39 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/viz/test/viz_test_suite.h"
+
+#include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
+#include "base/threading/thread_id_name_manager.h"
+#include "components/viz/test/paths.h"
+#include "ui/gl/test/gl_surface_test_support.h"
+
+namespace viz {
+
+VizTestSuite::VizTestSuite(int argc, char** argv)
+    : base::TestSuite(argc, argv) {}
+
+VizTestSuite::~VizTestSuite() = default;
+
+void VizTestSuite::Initialize() {
+  base::TestSuite::Initialize();
+  gl::GLSurfaceTestSupport::InitializeOneOff();
+  Paths::RegisterPathProvider();
+
+  message_loop_ = base::MakeUnique<base::MessageLoop>();
+
+  base::ThreadIdNameManager::GetInstance()->SetName(
+      base::PlatformThread::CurrentId(), "Main");
+
+  base::DiscardableMemoryAllocator::SetInstance(&discardable_memory_allocator_);
+}
+
+void VizTestSuite::Shutdown() {
+  message_loop_ = nullptr;
+
+  base::TestSuite::Shutdown();
+}
+
+}  // namespace viz
diff --git a/components/viz/test/viz_test_suite.h b/components/viz/test/viz_test_suite.h
new file mode 100644
index 0000000..ffc1353
--- /dev/null
+++ b/components/viz/test/viz_test_suite.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 COMPONENTS_VIZ_TEST_VIZ_TEST_SUITE_H_
+#define COMPONENTS_VIZ_TEST_VIZ_TEST_SUITE_H_
+
+#include <memory>
+
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/test/test_discardable_memory_allocator.h"
+#include "base/test/test_suite.h"
+
+namespace base {
+class MessageLoop;
+}
+
+namespace viz {
+
+class VizTestSuite : public base::TestSuite {
+ public:
+  VizTestSuite(int argc, char** argv);
+  ~VizTestSuite() override;
+
+ protected:
+  // Overridden from base::TestSuite:
+  void Initialize() override;
+  void Shutdown() override;
+
+ private:
+  std::unique_ptr<base::MessageLoop> message_loop_;
+  base::TestDiscardableMemoryAllocator discardable_memory_allocator_;
+
+  DISALLOW_COPY_AND_ASSIGN(VizTestSuite);
+};
+
+}  // namespace viz
+
+#endif  // COMPONENTS_VIZ_TEST_VIZ_TEST_SUITE_H_
diff --git a/components/viz/viz.gni b/components/viz/viz.gni
new file mode 100644
index 0000000..5df8b1ab
--- /dev/null
+++ b/components/viz/viz.gni
@@ -0,0 +1,57 @@
+# 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.
+
+import("//testing/test.gni")
+
+viz_remove_configs = []
+viz_add_configs = [ "//build/config:precompiled_headers" ]
+
+if (!is_debug && (is_win || is_android)) {
+  viz_remove_configs += [ "//build/config/compiler:default_optimization" ]
+  viz_add_configs += [ "//build/config/compiler:optimize_max" ]
+}
+
+template("viz_source_set") {
+  source_set(target_name) {
+    forward_variables_from(invoker, "*", [ "configs" ])
+    if (defined(invoker.configs)) {
+      configs += invoker.configs
+    }
+    configs -= viz_remove_configs
+    configs += viz_add_configs
+  }
+}
+
+template("viz_component") {
+  component(target_name) {
+    forward_variables_from(invoker, "*", [ "configs" ])
+    if (defined(invoker.configs)) {
+      configs += invoker.configs
+    }
+    configs -= viz_remove_configs
+    configs += viz_add_configs
+  }
+}
+
+template("viz_static_library") {
+  static_library(target_name) {
+    forward_variables_from(invoker, "*", [ "configs" ])
+    if (defined(invoker.configs)) {
+      configs += invoker.configs
+    }
+    configs -= viz_remove_configs
+    configs += viz_add_configs
+  }
+}
+
+template("viz_test") {
+  test(target_name) {
+    forward_variables_from(invoker, "*", [ "configs" ])
+    if (defined(invoker.configs)) {
+      configs += invoker.configs
+    }
+    configs -= viz_remove_configs
+    configs += viz_add_configs
+  }
+}
diff --git a/content/browser/android/dialog_overlay_impl.cc b/content/browser/android/dialog_overlay_impl.cc
index 8ea7141..5be3327 100644
--- a/content/browser/android/dialog_overlay_impl.cc
+++ b/content/browser/android/dialog_overlay_impl.cc
@@ -25,21 +25,44 @@
                   jlong high,
                   jlong low) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  return reinterpret_cast<jlong>(new DialogOverlayImpl(
-      obj, base::UnguessableToken::Deserialize(high, low)));
+
+  RenderFrameHostImpl* rfhi =
+      content::RenderFrameHostImpl::FromOverlayRoutingToken(
+          base::UnguessableToken::Deserialize(high, low));
+
+  if (!rfhi)
+    return 0;
+
+  WebContentsImpl* web_contents_impl = static_cast<WebContentsImpl*>(
+      content::WebContents::FromRenderFrameHost(rfhi));
+
+  // If the overlay would not be immediately used, fail the request.
+  if (!rfhi->IsCurrent() || web_contents_impl->IsHidden())
+    return 0;
+
+  ContentViewCoreImpl* cvc =
+      content::ContentViewCoreImpl::FromWebContents(web_contents_impl);
+
+  if (!cvc)
+    return 0;
+
+  return reinterpret_cast<jlong>(
+      new DialogOverlayImpl(obj, rfhi, web_contents_impl, cvc));
 }
 
 DialogOverlayImpl::DialogOverlayImpl(const JavaParamRef<jobject>& obj,
-                                     const base::UnguessableToken& token)
-    : token_(token), cvc_(nullptr) {
+                                     RenderFrameHostImpl* rfhi,
+                                     WebContents* web_contents,
+                                     ContentViewCoreImpl* cvc)
+    : WebContentsObserver(web_contents), rfhi_(rfhi), cvc_(cvc) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  DCHECK(rfhi_);
+  DCHECK(cvc_);
 
   JNIEnv* env = AttachCurrentThread();
   obj_ = JavaObjectWeakGlobalRef(env, obj);
 
-  cvc_ = GetContentViewCore();
-  if (cvc_)
-    cvc_->AddObserver(this);
+  cvc_->AddObserver(this);
 
   // Note that we're not allowed to call back into |obj| before it calls
   // CompleteInit.  However, the observer won't actually call us back until the
@@ -50,13 +73,6 @@
 void DialogOverlayImpl::CompleteInit(JNIEnv* env,
                                      const JavaParamRef<jobject>& obj) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
-  // If there's no CVC, then notify our caller.
-  if (!cvc_) {
-    Java_DialogOverlayImpl_onDismissed(env, obj.obj());
-    return;
-  }
-
   // Send the initial token, if there is one.  The observer will notify us about
   // changes only.
   if (ui::WindowAndroid* window = cvc_->GetWindowAndroid()) {
@@ -73,6 +89,17 @@
   DCHECK(!cvc_);
 }
 
+void DialogOverlayImpl::Stop() {
+  UnregisterForTokensIfNeeded();
+
+  JNIEnv* env = AttachCurrentThread();
+  ScopedJavaLocalRef<jobject> obj = obj_.get(env);
+  if (!obj.is_null())
+    Java_DialogOverlayImpl_onDismissed(env, obj.obj());
+
+  obj_.reset();
+}
+
 void DialogOverlayImpl::Destroy(JNIEnv* env, const JavaParamRef<jobject>& obj) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   UnregisterForTokensIfNeeded();
@@ -101,16 +128,40 @@
 
   cvc_->RemoveObserver(this);
   cvc_ = nullptr;
+  rfhi_ = nullptr;
 }
 
 void DialogOverlayImpl::OnContentViewCoreDestroyed() {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  cvc_ = nullptr;
+  // We will receive a destruction notification via WebContentsDestroyed().
+}
 
-  JNIEnv* env = AttachCurrentThread();
-  ScopedJavaLocalRef<jobject> obj = obj_.get(env);
-  if (!obj.is_null())
-    Java_DialogOverlayImpl_onDismissed(env, obj.obj());
+void DialogOverlayImpl::RenderFrameDeleted(RenderFrameHost* render_frame_host) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  if (render_frame_host == rfhi_)
+    Stop();
+}
+
+void DialogOverlayImpl::RenderFrameHostChanged(RenderFrameHost* old_host,
+                                               RenderFrameHost* new_host) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  if (old_host == rfhi_)
+    Stop();
+}
+
+void DialogOverlayImpl::FrameDeleted(RenderFrameHost* render_frame_host) {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  if (render_frame_host == rfhi_)
+    Stop();
+}
+
+void DialogOverlayImpl::WasHidden() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  Stop();
+}
+
+void DialogOverlayImpl::WebContentsDestroyed() {
+  DCHECK_CURRENTLY_ON(BrowserThread::UI);
+  Stop();
 }
 
 void DialogOverlayImpl::OnAttachedToWindow() {
@@ -134,30 +185,6 @@
     Java_DialogOverlayImpl_onWindowToken(env, obj.obj(), nullptr);
 }
 
-ContentViewCoreImpl* DialogOverlayImpl::GetContentViewCore() {
-  // Get the frame from the token.
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  content::RenderFrameHost* frame =
-      content::RenderFrameHostImpl::FromOverlayRoutingToken(token_);
-  if (!frame) {
-    DVLOG(1) << "Cannot find frame host for token " << token_;
-    return nullptr;
-  }
-
-  content::WebContents* web_contents =
-      content::WebContents::FromRenderFrameHost(frame);
-  DCHECK(web_contents);
-
-  content::ContentViewCoreImpl* cvc =
-      content::ContentViewCoreImpl::FromWebContents(web_contents);
-  if (!cvc) {
-    DVLOG(1) << "Cannot find cvc for token " << token_;
-    return nullptr;
-  }
-
-  return cvc;
-}
-
 static jint RegisterSurface(JNIEnv* env,
                             const base::android::JavaParamRef<jclass>& jcaller,
                             const JavaParamRef<jobject>& surface) {
diff --git a/content/browser/android/dialog_overlay_impl.h b/content/browser/android/dialog_overlay_impl.h
index 82d44e3..c5c328b2 100644
--- a/content/browser/android/dialog_overlay_impl.h
+++ b/content/browser/android/dialog_overlay_impl.h
@@ -11,6 +11,7 @@
 #include "base/unguessable_token.h"
 #include "content/browser/android/content_view_core_impl.h"
 #include "content/browser/android/content_view_core_impl_observer.h"
+#include "content/public/browser/web_contents_observer.h"
 
 namespace content {
 
@@ -18,7 +19,8 @@
 // java side.  When the ContentViewCore for the provided token is attached or
 // detached from a WindowAndroid, we get the Android window token and notify the
 // java side.
-class DialogOverlayImpl : public ContentViewCoreImplObserver {
+class DialogOverlayImpl : public ContentViewCoreImplObserver,
+                          public WebContentsObserver {
  public:
   // Registers the JNI methods for DialogOverlayImpl.
   static bool RegisterDialogOverlayImpl(JNIEnv* env);
@@ -26,7 +28,9 @@
   // This may not call back into |obj| directly, but must post.  This is because
   // |obj| is still being initialized.
   DialogOverlayImpl(const base::android::JavaParamRef<jobject>& obj,
-                    const base::UnguessableToken& token);
+                    RenderFrameHostImpl* rfhi,
+                    WebContents* web_contents,
+                    ContentViewCoreImpl* cvc);
   ~DialogOverlayImpl() override;
 
   // Called when the java side is ready for token / dismissed callbacks.  May
@@ -49,17 +53,26 @@
   void OnAttachedToWindow() override;
   void OnDetachedFromWindow() override;
 
+  // WebContentsObserver
+  void WasHidden() override;
+  void WebContentsDestroyed() override;
+  void FrameDeleted(RenderFrameHost* render_frame_host) override;
+  void RenderFrameDeleted(RenderFrameHost* render_frame_host) override;
+  void RenderFrameHostChanged(RenderFrameHost* old_host,
+                              RenderFrameHost* new_host) override;
+
   // Unregister for tokens if we're registered, and clear |cvc_|.
   void UnregisterForTokensIfNeeded();
 
  private:
-  // Look up the ContentViewCore for |renderer_pid_| and |render_frame_id_|.
-  ContentViewCoreImpl* GetContentViewCore();
+  // Signals the overlay should be cleaned up and no longer used.
+  void Stop();
 
   // Java object that owns us.
   JavaObjectWeakGlobalRef obj_;
 
-  base::UnguessableToken token_;
+  // RenderFrameHostImpl* associated with the given overlay routing token.
+  RenderFrameHostImpl* rfhi_;
 
   // ContentViewCoreImpl instance that we're registered with as an observer.
   ContentViewCoreImpl* cvc_;
diff --git a/content/browser/compositor/gpu_process_transport_factory.cc b/content/browser/compositor/gpu_process_transport_factory.cc
index eee583b..49ee974 100644
--- a/content/browser/compositor/gpu_process_transport_factory.cc
+++ b/content/browser/compositor/gpu_process_transport_factory.cc
@@ -26,14 +26,14 @@
 #include "cc/raster/task_graph_runner.h"
 #include "cc/scheduler/begin_frame_source.h"
 #include "cc/scheduler/delay_based_time_source.h"
-#include "cc/surfaces/direct_layer_tree_frame_sink.h"
-#include "cc/surfaces/display.h"
-#include "cc/surfaces/display_scheduler.h"
 #include "cc/surfaces/frame_sink_manager.h"
 #include "components/viz/common/gl_helper.h"
 #include "components/viz/host/host_frame_sink_manager.h"
+#include "components/viz/service/display/display.h"
+#include "components/viz/service/display/display_scheduler.h"
 #include "components/viz/service/display_embedder/compositor_overlay_candidate_validator.h"
 #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
+#include "components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h"
 #include "content/browser/browser_main_loop.h"
 #include "content/browser/compositor/browser_compositor_output_surface.h"
 #include "content/browser/compositor/gpu_browser_compositor_output_surface.h"
@@ -195,7 +195,7 @@
   std::unique_ptr<cc::SyntheticBeginFrameSource> synthetic_begin_frame_source;
   std::unique_ptr<GpuVSyncBeginFrameSource> gpu_vsync_begin_frame_source;
   ReflectorImpl* reflector = nullptr;
-  std::unique_ptr<cc::Display> display;
+  std::unique_ptr<viz::Display> display;
   bool output_is_secure = false;
 };
 
@@ -597,12 +597,12 @@
         data->gpu_vsync_begin_frame_source.get());
   }
 
-  std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler(
+  auto scheduler = base::MakeUnique<viz::DisplayScheduler>(
       begin_frame_source, compositor->task_runner().get(),
-      display_output_surface->capabilities().max_frames_pending));
+      display_output_surface->capabilities().max_frames_pending);
 
   // The Display owns and uses the |display_output_surface| created above.
-  data->display = base::MakeUnique<cc::Display>(
+  data->display = base::MakeUnique<viz::Display>(
       viz::ServerSharedBitmapManager::current(), GetGpuMemoryBufferManager(),
       renderer_settings_, compositor->frame_sink_id(),
       std::move(display_output_surface), std::move(scheduler),
@@ -620,12 +620,12 @@
   // same ContextProvider as the Display's output surface.
   auto layer_tree_frame_sink =
       vulkan_context_provider
-          ? base::MakeUnique<cc::DirectLayerTreeFrameSink>(
+          ? base::MakeUnique<viz::DirectLayerTreeFrameSink>(
                 compositor->frame_sink_id(), GetFrameSinkManager(),
                 data->display.get(),
                 static_cast<scoped_refptr<cc::VulkanContextProvider>>(
                     vulkan_context_provider))
-          : base::MakeUnique<cc::DirectLayerTreeFrameSink>(
+          : base::MakeUnique<viz::DirectLayerTreeFrameSink>(
                 compositor->frame_sink_id(), GetFrameSinkManager(),
                 data->display.get(), context_provider,
                 shared_worker_context_provider_, GetGpuMemoryBufferManager(),
diff --git a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
index c8d25948..5867817 100644
--- a/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
+++ b/content/browser/devtools/protocol/devtools_protocol_browsertest.cc
@@ -447,7 +447,6 @@
   ASSERT_TRUE(content::ExecuteScript(
       shell()->web_contents()->GetRenderViewHost(),
       "function handleKeyEvent(event) {"
-        "domAutomationController.setAutomationId(0);"
         "domAutomationController.send(event.key);"
       "}"
       "document.body.addEventListener('keydown', handleKeyEvent);"
diff --git a/content/browser/devtools/protocol/input_handler.cc b/content/browser/devtools/protocol/input_handler.cc
index cc419a3..0e517ca 100644
--- a/content/browser/devtools/protocol/input_handler.cc
+++ b/content/browser/devtools/protocol/input_handler.cc
@@ -27,11 +27,13 @@
 
 namespace {
 
-gfx::PointF CssPixelsToPointF(int x, int y, float page_scale_factor) {
+gfx::PointF CssPixelsToPointF(double x, double y, float page_scale_factor) {
   return gfx::PointF(x * page_scale_factor, y * page_scale_factor);
 }
 
-gfx::Vector2dF CssPixelsToVector2dF(int x, int y, float page_scale_factor) {
+gfx::Vector2dF CssPixelsToVector2dF(double x,
+                                    double y,
+                                    float page_scale_factor) {
   return gfx::Vector2dF(x * page_scale_factor, y * page_scale_factor);
 }
 
@@ -344,8 +346,8 @@
 
 void InputHandler::DispatchMouseEvent(
     const std::string& type,
-    int x,
-    int y,
+    double x,
+    double y,
     Maybe<int> modifiers,
     Maybe<double> timestamp,
     Maybe<std::string> button,
@@ -476,8 +478,8 @@
 }
 
 void InputHandler::SynthesizePinchGesture(
-    int x,
-    int y,
+    double x,
+    double y,
     double scale_factor,
     Maybe<int> relative_speed,
     Maybe<std::string> gesture_source_type,
@@ -515,12 +517,12 @@
 }
 
 void InputHandler::SynthesizeScrollGesture(
-    int x,
-    int y,
-    Maybe<int> x_distance,
-    Maybe<int> y_distance,
-    Maybe<int> x_overscroll,
-    Maybe<int> y_overscroll,
+    double x,
+    double y,
+    Maybe<double> x_distance,
+    Maybe<double> y_distance,
+    Maybe<double> x_overscroll,
+    Maybe<double> y_overscroll,
     Maybe<bool> prevent_fling,
     Maybe<int> speed,
     Maybe<std::string> gesture_source_type,
@@ -621,8 +623,8 @@
 }
 
 void InputHandler::SynthesizeTapGesture(
-    int x,
-    int y,
+    double x,
+    double y,
     Maybe<int> duration,
     Maybe<int> tap_count,
     Maybe<std::string> gesture_source_type,
diff --git a/content/browser/devtools/protocol/input_handler.h b/content/browser/devtools/protocol/input_handler.h
index 50d2612..ec1e10d 100644
--- a/content/browser/devtools/protocol/input_handler.h
+++ b/content/browser/devtools/protocol/input_handler.h
@@ -57,8 +57,8 @@
 
   void DispatchMouseEvent(
       const std::string& type,
-      int x,
-      int y,
+      double x,
+      double y,
       Maybe<int> modifiers,
       Maybe<double> timestamp,
       Maybe<std::string> button,
@@ -78,20 +78,20 @@
   Response SetIgnoreInputEvents(bool ignore) override;
 
   void SynthesizePinchGesture(
-      int x,
-      int y,
+      double x,
+      double y,
       double scale_factor,
       Maybe<int> relative_speed,
       Maybe<std::string> gesture_source_type,
       std::unique_ptr<SynthesizePinchGestureCallback> callback) override;
 
   void SynthesizeScrollGesture(
-      int x,
-      int y,
-      Maybe<int> x_distance,
-      Maybe<int> y_distance,
-      Maybe<int> x_overscroll,
-      Maybe<int> y_overscroll,
+      double x,
+      double y,
+      Maybe<double> x_distance,
+      Maybe<double> y_distance,
+      Maybe<double> x_overscroll,
+      Maybe<double> y_overscroll,
       Maybe<bool> prevent_fling,
       Maybe<int> speed,
       Maybe<std::string> gesture_source_type,
@@ -101,8 +101,8 @@
       std::unique_ptr<SynthesizeScrollGestureCallback> callback) override;
 
   void SynthesizeTapGesture(
-      int x,
-      int y,
+      double x,
+      double y,
       Maybe<int> duration,
       Maybe<int> tap_count,
       Maybe<std::string> gesture_source_type,
diff --git a/content/browser/dom_storage/local_storage_context_mojo.cc b/content/browser/dom_storage/local_storage_context_mojo.cc
index b4403bcd..ad15ed2c 100644
--- a/content/browser/dom_storage/local_storage_context_mojo.cc
+++ b/content/browser/dom_storage/local_storage_context_mojo.cc
@@ -7,6 +7,7 @@
 #include <inttypes.h>
 #include <cctype>  // for std::isalnum
 #include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/string_number_conversions.h"
@@ -52,6 +53,10 @@
 const int64_t kMinSchemaVersion = 1;
 const int64_t kCurrentSchemaVersion = 1;
 
+// After this many consecutive commit errors we'll throw away the entire
+// database.
+const int kCommitErrorThreshold = 8;
+
 // Use a smaller block cache on android. Because of the extra caching done in
 // LevelDBWrapperImpl the block cache isn't particularly useful, but it still
 // provides some benefit with speeding up compaction. And since this is a once
@@ -62,17 +67,6 @@
 const size_t kMaxBlockCacheSize = 2 * 1024 * 1024;
 #endif
 
-const char kStorageOpenHistogramName[] = "LocalStorageContext.OpenError";
-// These values are written to logs.  New enum values can be added, but existing
-// enums must never be renumbered or deleted and reused.
-enum class LocalStorageOpenHistogram {
-  DIRECTORY_OPEN_FAILED = 0,
-  DATABASE_OPEN_FAILED = 1,
-  INVALID_VERSION = 2,
-  VERSION_READ_ERROR = 3,
-  MAX
-};
-
 // Limits on the cache size and number of areas in memory, over which the areas
 // are purged.
 #if defined(OS_ANDROID)
@@ -258,6 +252,8 @@
           base::Bind(base::IgnoreResult(&sql::Connection::Delete),
                      sql_db_path()));
     }
+
+    context_->OnCommitResult(error);
   }
 
   void MigrateData(LevelDBWrapperImpl::ValueMapCallback callback) override {
@@ -380,6 +376,15 @@
     it.second->level_db_wrapper()->ScheduleImmediateCommit();
 }
 
+void LocalStorageContextMojo::FlushOriginForTesting(const url::Origin& origin) {
+  if (connection_state_ != CONNECTION_FINISHED)
+    return;
+  const auto& it = level_db_wrappers_.find(origin);
+  if (it == level_db_wrappers_.end())
+    return;
+  it->second->level_db_wrapper()->ScheduleImmediateCommit();
+}
+
 void LocalStorageContextMojo::ShutdownAndDelete() {
   DCHECK_NE(connection_state_, CONNECTION_SHUTDOWN);
 
@@ -564,7 +569,6 @@
 
 void LocalStorageContextMojo::InitiateConnection(bool in_memory_only) {
   DCHECK_EQ(connection_state_, CONNECTION_IN_PROGRESS);
-
   // Unit tests might not always have a Connector, use in-memory only if that
   // happens.
   if (!connector_) {
@@ -598,10 +602,7 @@
     UMA_HISTOGRAM_ENUMERATION("LocalStorageContext.DirectoryOpenError",
                               -static_cast<base::File::Error>(err),
                               -base::File::FILE_ERROR_MAX);
-    UMA_HISTOGRAM_ENUMERATION(
-        kStorageOpenHistogramName,
-        static_cast<int>(LocalStorageOpenHistogram::DIRECTORY_OPEN_FAILED),
-        static_cast<int>(LocalStorageOpenHistogram::MAX));
+    LogDatabaseOpenResult(OpenResult::DIRECTORY_OPEN_FAILED);
     OnDatabaseOpened(false, leveldb::mojom::DatabaseError::OK);
     return;
   }
@@ -647,13 +648,10 @@
                                 leveldb::GetLevelDBStatusUMAValue(status),
                                 leveldb_env::LEVELDB_STATUS_MAX);
     }
-    UMA_HISTOGRAM_ENUMERATION(
-        kStorageOpenHistogramName,
-        static_cast<int>(LocalStorageOpenHistogram::DATABASE_OPEN_FAILED),
-        static_cast<int>(LocalStorageOpenHistogram::MAX));
+    LogDatabaseOpenResult(OpenResult::DATABASE_OPEN_FAILED);
     // If we failed to open the database, try to delete and recreate the
     // database, or ultimately fallback to an in-memory database.
-    DeleteAndRecreateDatabase();
+    DeleteAndRecreateDatabase("LocalStorageContext.OpenResultAfterOpenFailed");
     return;
   }
 
@@ -681,11 +679,9 @@
     if (!base::StringToInt64(leveldb::Uint8VectorToStdString(value),
                              &db_version) ||
         db_version < kMinSchemaVersion || db_version > kCurrentSchemaVersion) {
-      UMA_HISTOGRAM_ENUMERATION(
-          kStorageOpenHistogramName,
-          static_cast<int>(LocalStorageOpenHistogram::INVALID_VERSION),
-          static_cast<int>(LocalStorageOpenHistogram::MAX));
-      DeleteAndRecreateDatabase();
+      LogDatabaseOpenResult(OpenResult::INVALID_VERSION);
+      DeleteAndRecreateDatabase(
+          "LocalStorageContext.OpenResultAfterInvalidVersion");
       return;
     }
 
@@ -695,11 +691,9 @@
     UMA_HISTOGRAM_ENUMERATION("LocalStorageContext.ReadVersionError",
                               leveldb::GetLevelDBStatusUMAValue(status),
                               leveldb_env::LEVELDB_STATUS_MAX);
-    UMA_HISTOGRAM_ENUMERATION(
-        kStorageOpenHistogramName,
-        static_cast<int>(LocalStorageOpenHistogram::VERSION_READ_ERROR),
-        static_cast<int>(LocalStorageOpenHistogram::MAX));
-    DeleteAndRecreateDatabase();
+    LogDatabaseOpenResult(OpenResult::VERSION_READ_ERROR);
+    DeleteAndRecreateDatabase(
+        "LocalStorageContext.OpenResultAfterReadVersionError");
     return;
   }
 
@@ -708,13 +702,18 @@
 
 void LocalStorageContextMojo::OnConnectionFinished() {
   DCHECK_EQ(connection_state_, CONNECTION_IN_PROGRESS);
-
-  // We no longer need the file service; we've either transferred |directory_|
-  // to the leveldb service, or we got a file error and no more is possible.
-  directory_.reset();
-  file_system_.reset();
-  if (!database_)
+  if (!database_) {
+    directory_.reset();
+    file_system_.reset();
     leveldb_service_.reset();
+  }
+
+  // If connection was opened successfully, reset tried_to_recreate_during_open_
+  // to enable recreating the database on future errors.
+  if (database_)
+    tried_to_recreate_during_open_ = false;
+
+  open_result_histogram_ = nullptr;
 
   // |database_| should be known to either be valid or invalid by now. Run our
   // delayed bindings.
@@ -724,35 +723,41 @@
   on_database_opened_callbacks_.clear();
 }
 
-void LocalStorageContextMojo::DeleteAndRecreateDatabase() {
-  // For now don't support deletion and recreation when already connected.
-  DCHECK_EQ(connection_state_, CONNECTION_IN_PROGRESS);
+void LocalStorageContextMojo::DeleteAndRecreateDatabase(
+    const char* histogram_name) {
+  // We're about to set database_ to null, so delete and LevelDBWrappers
+  // that might still be using the old database.
+  level_db_wrappers_.clear();
+
+  // Reset state to be in process of connecting. This will cause requests for
+  // LevelDBWrappers to be queued until the connection is complete.
+  connection_state_ = CONNECTION_IN_PROGRESS;
+  commit_error_count_ = 0;
+  database_ = nullptr;
+  open_result_histogram_ = histogram_name;
 
   bool recreate_in_memory = false;
 
   // If tried to recreate database on disk already, try again but this time
   // in memory.
-  if (tried_to_recreate_ && !subdirectory_.empty()) {
+  if (tried_to_recreate_during_open_ && !subdirectory_.empty()) {
     recreate_in_memory = true;
-  } else if (tried_to_recreate_) {
+  } else if (tried_to_recreate_during_open_) {
     // Give up completely, run without any database.
-    database_ = nullptr;
     OnConnectionFinished();
     return;
   }
 
-  tried_to_recreate_ = true;
+  tried_to_recreate_during_open_ = true;
 
   // Unit tests might not have a bound file_service_, in which case there is
   // nothing to retry.
   if (!file_system_.is_bound()) {
-    database_ = nullptr;
     OnConnectionFinished();
     return;
   }
 
-  // Close and destroy database, and try again.
-  database_ = nullptr;
+  // Destroy database, and try again.
   if (directory_.is_bound()) {
     leveldb_service_->Destroy(
         std::move(directory_), "leveldb",
@@ -919,4 +924,41 @@
   }
 }
 
+void LocalStorageContextMojo::OnCommitResult(
+    leveldb::mojom::DatabaseError error) {
+  DCHECK_EQ(connection_state_, CONNECTION_FINISHED);
+  if (error == leveldb::mojom::DatabaseError::OK) {
+    commit_error_count_ = 0;
+    return;
+  }
+
+  commit_error_count_++;
+  if (commit_error_count_ > kCommitErrorThreshold) {
+    if (tried_to_recover_from_commit_errors_) {
+      // We already tried to recover from a high commit error rate before, but
+      // are still having problems: there isn't really anything left to try, so
+      // just ignore errors.
+      return;
+    }
+    tried_to_recover_from_commit_errors_ = true;
+
+    // Deleting LevelDBWrappers in here could cause more commits (and commit
+    // errors), but those commits won't reach OnCommitResult because the wrapper
+    // will have been deleted before the commit finishes.
+    DeleteAndRecreateDatabase(
+        "LocalStorageContext.OpenResultAfterCommitErrors");
+  }
+}
+
+void LocalStorageContextMojo::LogDatabaseOpenResult(OpenResult result) {
+  if (result != OpenResult::SUCCESS) {
+    UMA_HISTOGRAM_ENUMERATION("LocalStorageContext.OpenError", result,
+                              OpenResult::MAX);
+  }
+  if (open_result_histogram_) {
+    base::UmaHistogramEnumeration(open_result_histogram_, result,
+                                  OpenResult::MAX);
+  }
+}
+
 }  // namespace content
diff --git a/content/browser/dom_storage/local_storage_context_mojo.h b/content/browser/dom_storage/local_storage_context_mojo.h
index d471de2..0dda7b2 100644
--- a/content/browser/dom_storage/local_storage_context_mojo.h
+++ b/content/browser/dom_storage/local_storage_context_mojo.h
@@ -55,6 +55,7 @@
   // Like DeleteStorage(), but also deletes storage for all sub-origins.
   void DeleteStorageForPhysicalOrigin(const url::Origin& origin);
   void Flush();
+  void FlushOriginForTesting(const url::Origin& origin);
 
   // Used by content settings to alter the behavior around
   // what data to keep and what data to discard at shutdown.
@@ -104,7 +105,7 @@
   void OnGotDatabaseVersion(leveldb::mojom::DatabaseError status,
                             const std::vector<uint8_t>& value);
   void OnConnectionFinished();
-  void DeleteAndRecreateDatabase();
+  void DeleteAndRecreateDatabase(const char* histogram_name);
   void OnDBDestroyed(bool recreate_in_memory,
                      leveldb::mojom::DatabaseError status);
 
@@ -129,6 +130,21 @@
   void OnShutdownComplete(leveldb::mojom::DatabaseError error);
 
   void GetStatistics(size_t* total_cache_size, size_t* unused_wrapper_count);
+  void OnCommitResult(leveldb::mojom::DatabaseError error);
+  void OnReconnectedToDB();
+
+  // These values are written to logs.  New enum values can be added, but
+  // existing enums must never be renumbered or deleted and reused.
+  enum class OpenResult {
+    DIRECTORY_OPEN_FAILED = 0,
+    DATABASE_OPEN_FAILED = 1,
+    INVALID_VERSION = 2,
+    VERSION_READ_ERROR = 3,
+    SUCCESS = 4,
+    MAX
+  };
+
+  void LogDatabaseOpenResult(OpenResult result);
 
   std::unique_ptr<service_manager::Connector> connector_;
   const base::FilePath subdirectory_;
@@ -151,7 +167,7 @@
 
   leveldb::mojom::LevelDBServicePtr leveldb_service_;
   leveldb::mojom::LevelDBDatabaseAssociatedPtr database_;
-  bool tried_to_recreate_ = false;
+  bool tried_to_recreate_during_open_ = false;
 
   std::vector<base::OnceClosure> on_database_opened_callbacks_;
 
@@ -164,6 +180,13 @@
   base::FilePath old_localstorage_path_;
 
   bool is_low_end_device_;
+  // Counts consecutive commit errors. If this number reaches a threshold, the
+  // whole database is thrown away.
+  int commit_error_count_ = 0;
+  bool tried_to_recover_from_commit_errors_ = false;
+
+  // Name of an extra histogram to log open results to, if not null.
+  const char* open_result_histogram_ = nullptr;
 
   base::WeakPtrFactory<LocalStorageContextMojo> weak_ptr_factory_;
 };
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 902d97c..452e1acd 100644
--- a/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
+++ b/content/browser/dom_storage/local_storage_context_mojo_unittest.cc
@@ -24,6 +24,7 @@
 #include "mojo/public/cpp/bindings/associated_binding.h"
 #include "mojo/public/cpp/bindings/binding.h"
 #include "mojo/public/cpp/bindings/binding_set.h"
+#include "mojo/public/cpp/bindings/strong_associated_binding.h"
 #include "services/file/file_service.h"
 #include "services/file/public/interfaces/constants.mojom.h"
 #include "services/file/user_id_map.h"
@@ -823,6 +824,8 @@
   }
 
   void TearDown() override {
+    service_manager::ServiceContext::ClearGlobalBindersForTesting(
+        file::mojom::kServiceName);
     ServiceTest::TearDown();
   }
 
@@ -880,7 +883,6 @@
   mojom::LevelDBWrapperPtr wrapper;
   context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
                             MakeRequest(&wrapper));
-
   DoTestPut(context, key, value);
   std::vector<uint8_t> result;
   EXPECT_TRUE(DoTestGet(context, key, &result));
@@ -1061,4 +1063,355 @@
   context->ShutdownAndDelete();
 }
 
+namespace {
+
+class MockLevelDBService : public leveldb::mojom::LevelDBService {
+ public:
+  void Open(filesystem::mojom::DirectoryPtr,
+            const std::string& dbname,
+            const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>&
+                memory_dump_id,
+            leveldb::mojom::LevelDBDatabaseAssociatedRequest request,
+            OpenCallback callback) override {
+    open_requests_.push_back(
+        {false, dbname, std::move(request), std::move(callback)});
+    if (on_open_callback_)
+      on_open_callback_.Run();
+  }
+
+  void OpenWithOptions(
+      leveldb::mojom::OpenOptionsPtr options,
+      filesystem::mojom::DirectoryPtr,
+      const std::string& dbname,
+      const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>&
+          memory_dump_id,
+      leveldb::mojom::LevelDBDatabaseAssociatedRequest request,
+      OpenCallback callback) override {
+    open_requests_.push_back(
+        {false, dbname, std::move(request), std::move(callback)});
+    if (on_open_callback_)
+      on_open_callback_.Run();
+  }
+
+  void OpenInMemory(
+      const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>&
+          memory_dump_id,
+      leveldb::mojom::LevelDBDatabaseAssociatedRequest request,
+      OpenCallback callback) override {
+    open_requests_.push_back(
+        {true, "", std::move(request), std::move(callback)});
+    if (on_open_callback_)
+      on_open_callback_.Run();
+  }
+
+  void Destroy(filesystem::mojom::DirectoryPtr,
+               const std::string& dbname,
+               DestroyCallback callback) override {
+    destroy_requests_.push_back({dbname});
+    std::move(callback).Run(leveldb::mojom::DatabaseError::OK);
+  }
+
+  struct OpenRequest {
+    bool in_memory;
+    std::string dbname;
+    leveldb::mojom::LevelDBDatabaseAssociatedRequest request;
+    OpenCallback callback;
+  };
+  std::vector<OpenRequest> open_requests_;
+  base::Closure on_open_callback_;
+
+  struct DestroyRequest {
+    std::string dbname;
+  };
+  std::vector<DestroyRequest> destroy_requests_;
+
+  void Bind(const service_manager::BindSourceInfo& source_info,
+            const std::string& interface_name,
+            mojo::ScopedMessagePipeHandle interface_pipe) {
+    bindings_.AddBinding(
+        this, leveldb::mojom::LevelDBServiceRequest(std::move(interface_pipe)));
+  }
+
+ private:
+  mojo::BindingSet<leveldb::mojom::LevelDBService> bindings_;
+};
+
+class MockLevelDBDatabaseErrorOnWrite : public MockLevelDBDatabase {
+ public:
+  explicit MockLevelDBDatabaseErrorOnWrite(
+      std::map<std::vector<uint8_t>, std::vector<uint8_t>>* mock_data)
+      : MockLevelDBDatabase(mock_data) {}
+
+  void Write(std::vector<leveldb::mojom::BatchedOperationPtr> operations,
+             WriteCallback callback) override {
+    std::move(callback).Run(leveldb::mojom::DatabaseError::IO_ERROR);
+  }
+};
+
+}  // namespace
+
+TEST_F(LocalStorageContextMojoTestWithService, RecreateOnCommitFailure) {
+  MockLevelDBService mock_leveldb_service;
+  service_manager::ServiceContext::SetGlobalBinderForTesting(
+      file::mojom::kServiceName, leveldb::mojom::LevelDBService::Name_,
+      base::Bind(&MockLevelDBService::Bind,
+                 base::Unretained(&mock_leveldb_service)));
+
+  std::map<std::vector<uint8_t>, std::vector<uint8_t>> test_data;
+
+  base::FilePath test_path(FILE_PATH_LITERAL("test_path"));
+  auto* context = new LocalStorageContextMojo(
+      base::ThreadTaskRunnerHandle::Get(), connector(), nullptr,
+      base::FilePath(), test_path, nullptr);
+
+  auto key = StdStringToUint8Vector("key");
+  auto value = StdStringToUint8Vector("value");
+
+  // Open three connections to the database. Two to the same origin, and a third
+  // to a different origin.
+  mojom::LevelDBWrapperPtr wrapper1;
+  mojom::LevelDBWrapperPtr wrapper2;
+  mojom::LevelDBWrapperPtr wrapper3;
+  {
+    base::RunLoop loop;
+    mock_leveldb_service.on_open_callback_ = loop.QuitClosure();
+    context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+                              MakeRequest(&wrapper1));
+    context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+                              MakeRequest(&wrapper2));
+    context->OpenLocalStorage(url::Origin(GURL("http://example.com")),
+                              MakeRequest(&wrapper3));
+    loop.Run();
+  }
+
+  // Add observers to the first two connections.
+  TestLevelDBObserver observer1;
+  wrapper1->AddObserver(observer1.Bind());
+  TestLevelDBObserver observer2;
+  wrapper2->AddObserver(observer2.Bind());
+
+  // Verify one attempt was made to open the database, and connect that request
+  // with a database implementation that always fails on write.
+  ASSERT_EQ(1u, mock_leveldb_service.open_requests_.size());
+  auto& open_request = mock_leveldb_service.open_requests_[0];
+  auto mock_db = mojo::MakeStrongAssociatedBinding(
+      base::MakeUnique<MockLevelDBDatabaseErrorOnWrite>(&test_data),
+      std::move(open_request.request));
+  std::move(open_request.callback).Run(leveldb::mojom::DatabaseError::OK);
+  mock_leveldb_service.open_requests_.clear();
+
+  // Setup a RunLoop so we can wait until LocalStorageContextMojo tries to
+  // reconnect to the database, which should happen after several commit
+  // errors.
+  base::RunLoop reopen_loop;
+  mock_leveldb_service.on_open_callback_ = reopen_loop.QuitClosure();
+
+  // Start a put operation on the third connection before starting to commit
+  // a lot of data on the first origin. This put operation should result in a
+  // pending commit that will get cancelled when the database connection is
+  // closed.
+  wrapper3->Put(key, value, "source",
+                base::Bind([](bool success) { EXPECT_TRUE(success); }));
+
+  // Repeatedly write data to the database, to trigger enough commit errors.
+  size_t values_written = 0;
+  while (!wrapper1.encountered_error()) {
+    base::RunLoop put_loop;
+    // Every write needs to be different to make sure there actually is a
+    // change to commit.
+    value[0]++;
+    wrapper1.set_connection_error_handler(put_loop.QuitClosure());
+    wrapper1->Put(key, value, "source",
+                  base::Bind(
+                      [](base::Closure quit_closure, bool success) {
+                        EXPECT_TRUE(success);
+                        quit_closure.Run();
+                      },
+                      put_loop.QuitClosure()));
+    put_loop.RunUntilIdle();
+    values_written++;
+    // And we need to flush after every change. Otherwise changes get batched up
+    // and only one commit is done some time later.
+    context->FlushOriginForTesting(url::Origin(GURL("http://foobar.com")));
+  }
+  // Make sure all messages to the DB have been processed (Flush above merely
+  // schedules a commit, but there is no guarantee about those having been
+  // processed yet).
+  if (mock_db)
+    mock_db->FlushForTesting();
+  // At this point enough commit failures should have happened to cause the
+  // connection to the database to have been severed.
+  EXPECT_FALSE(mock_db);
+
+  // The connection to the second wrapper should have closed as well.
+  EXPECT_TRUE(wrapper2.encountered_error());
+
+  // And the old database should have been destroyed.
+  EXPECT_EQ(1u, mock_leveldb_service.destroy_requests_.size());
+
+  // Reconnect wrapper1 to the database, and try to read a value.
+  context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+                            MakeRequest(&wrapper1));
+  base::RunLoop get_loop;
+  std::vector<uint8_t> result;
+  bool success = true;
+  wrapper1->Get(
+      key, base::Bind(&GetCallback, get_loop.QuitClosure(), &success, &result));
+
+  // Wait for LocalStorageContextMojo to try to reconnect to the database, and
+  // connect that new request to a properly functioning database.
+  reopen_loop.Run();
+  ASSERT_EQ(1u, mock_leveldb_service.open_requests_.size());
+  auto& reopen_request = mock_leveldb_service.open_requests_[0];
+  mock_db = mojo::MakeStrongAssociatedBinding(
+      base::MakeUnique<MockLevelDBDatabase>(&test_data),
+      std::move(reopen_request.request));
+  std::move(reopen_request.callback).Run(leveldb::mojom::DatabaseError::OK);
+  mock_leveldb_service.open_requests_.clear();
+
+  // And reading the value from the new wrapper should have failed (as the
+  // database is empty).
+  get_loop.Run();
+  EXPECT_FALSE(success);
+  wrapper1 = nullptr;
+
+  {
+    // Committing data should now work.
+    DoTestPut(context, key, value);
+    std::vector<uint8_t> result;
+    EXPECT_TRUE(DoTestGet(context, key, &result));
+    EXPECT_EQ(value, result);
+    EXPECT_FALSE(test_data.empty());
+  }
+
+  // Observers should have seen one Add event and a number of Change events for
+  // all commits until the connection was closed.
+  ASSERT_EQ(values_written, observer2.observations().size());
+  for (size_t i = 0; i < values_written; ++i) {
+    EXPECT_EQ(i ? TestLevelDBObserver::Observation::kChange
+                : TestLevelDBObserver::Observation::kAdd,
+              observer2.observations()[i].type);
+    EXPECT_EQ(Uint8VectorToStdString(key), observer2.observations()[i].key);
+  }
+}
+
+TEST_F(LocalStorageContextMojoTestWithService,
+       DontRecreateOnRepeatedCommitFailure) {
+  MockLevelDBService mock_leveldb_service;
+  service_manager::ServiceContext::SetGlobalBinderForTesting(
+      file::mojom::kServiceName, leveldb::mojom::LevelDBService::Name_,
+      base::Bind(&MockLevelDBService::Bind,
+                 base::Unretained(&mock_leveldb_service)));
+
+  std::map<std::vector<uint8_t>, std::vector<uint8_t>> test_data;
+
+  base::FilePath test_path(FILE_PATH_LITERAL("test_path"));
+  auto* context = new LocalStorageContextMojo(
+      base::ThreadTaskRunnerHandle::Get(), connector(), nullptr,
+      base::FilePath(), test_path, nullptr);
+
+  auto key = StdStringToUint8Vector("key");
+  auto value = StdStringToUint8Vector("value");
+
+  // Open a connection to the database.
+  mojom::LevelDBWrapperPtr wrapper;
+  {
+    base::RunLoop loop;
+    mock_leveldb_service.on_open_callback_ = loop.QuitClosure();
+    context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+                              MakeRequest(&wrapper));
+    loop.Run();
+  }
+
+  // Verify one attempt was made to open the database, and connect that request
+  // with a database implementation that always fails on write.
+  ASSERT_EQ(1u, mock_leveldb_service.open_requests_.size());
+  auto& open_request = mock_leveldb_service.open_requests_[0];
+  auto mock_db = mojo::MakeStrongAssociatedBinding(
+      base::MakeUnique<MockLevelDBDatabaseErrorOnWrite>(&test_data),
+      std::move(open_request.request));
+  std::move(open_request.callback).Run(leveldb::mojom::DatabaseError::OK);
+  mock_leveldb_service.open_requests_.clear();
+
+  // Setup a RunLoop so we can wait until LocalStorageContextMojo tries to
+  // reconnect to the database, which should happen after several commit
+  // errors.
+  base::RunLoop reopen_loop;
+  mock_leveldb_service.on_open_callback_ = reopen_loop.QuitClosure();
+
+  // Repeatedly write data to the database, to trigger enough commit errors.
+  while (!wrapper.encountered_error()) {
+    base::RunLoop put_loop;
+    // Every write needs to be different to make sure there actually is a
+    // change to commit.
+    value[0]++;
+    wrapper.set_connection_error_handler(put_loop.QuitClosure());
+    wrapper->Put(key, value, "source",
+                 base::Bind(
+                     [](base::Closure quit_closure, bool success) {
+                       EXPECT_TRUE(success);
+                       quit_closure.Run();
+                     },
+                     put_loop.QuitClosure()));
+    put_loop.RunUntilIdle();
+    // And we need to flush after every change. Otherwise changes get batched up
+    // and only one commit is done some time later.
+    context->FlushOriginForTesting(url::Origin(GURL("http://foobar.com")));
+  }
+  // Make sure all messages to the DB have been processed (Flush above merely
+  // schedules a commit, but there is no guarantee about those having been
+  // processed yet).
+  if (mock_db)
+    mock_db->FlushForTesting();
+  // At this point enough commit failures should have happened to cause the
+  // connection to the database to have been severed.
+  EXPECT_FALSE(mock_db);
+
+  // Wait for LocalStorageContextMojo to try to reconnect to the database, and
+  // connect that new request with a database implementation that always fails
+  // on write.
+  reopen_loop.Run();
+  ASSERT_EQ(1u, mock_leveldb_service.open_requests_.size());
+  auto& reopen_request = mock_leveldb_service.open_requests_[0];
+  mock_db = mojo::MakeStrongAssociatedBinding(
+      base::MakeUnique<MockLevelDBDatabaseErrorOnWrite>(&test_data),
+      std::move(reopen_request.request));
+  std::move(reopen_request.callback).Run(leveldb::mojom::DatabaseError::OK);
+  mock_leveldb_service.open_requests_.clear();
+
+  // The old database should also have been destroyed.
+  EXPECT_EQ(1u, mock_leveldb_service.destroy_requests_.size());
+
+  // Reconnect a wrapper to the database, and repeatedly write data to it again.
+  // This time all should just keep getting written, and commit errors are
+  // getting ignored.
+  context->OpenLocalStorage(url::Origin(GURL("http://foobar.com")),
+                            MakeRequest(&wrapper));
+  for (int i = 0; i < 64; ++i) {
+    base::RunLoop put_loop;
+    // Every write needs to be different to make sure there actually is a
+    // change to commit.
+    value[0]++;
+    wrapper.set_connection_error_handler(put_loop.QuitClosure());
+    wrapper->Put(key, value, "source",
+                 base::Bind(
+                     [](base::Closure quit_closure, bool success) {
+                       EXPECT_TRUE(success);
+                       quit_closure.Run();
+                     },
+                     put_loop.QuitClosure()));
+    put_loop.RunUntilIdle();
+    // And we need to flush after every change. Otherwise changes get batched up
+    // and only one commit is done some time later.
+    context->FlushOriginForTesting(url::Origin(GURL("http://foobar.com")));
+  }
+  // Make sure all messages to the DB have been processed (Flush above merely
+  // schedules a commit, but there is no guarantee about those having been
+  // processed yet).
+  if (mock_db)
+    mock_db->FlushForTesting();
+  EXPECT_TRUE(mock_db);
+  EXPECT_FALSE(wrapper.encountered_error());
+}
+
 }  // namespace content
diff --git a/content/browser/download/download_item_impl.h b/content/browser/download/download_item_impl.h
index b6d2214..369d336 100644
--- a/content/browser/download/download_item_impl.h
+++ b/content/browser/download/download_item_impl.h
@@ -36,14 +36,6 @@
     : public DownloadItem,
       public DownloadDestinationObserver {
  public:
-  enum ResumeMode {
-    RESUME_MODE_INVALID = 0,
-    RESUME_MODE_IMMEDIATE_CONTINUE,
-    RESUME_MODE_IMMEDIATE_RESTART,
-    RESUME_MODE_USER_CONTINUE,
-    RESUME_MODE_USER_RESTART
-  };
-
   // Information about the initial request that triggers the download. Most of
   // the fields are immutable after the DownloadItem is successfully created.
   // However, it is possible that the url chain is changed when resuming an
@@ -290,11 +282,6 @@
   // All remaining public interfaces virtual to allow for DownloadItemImpl
   // mocks.
 
-  // Determines the resume mode for an interrupted download. Requires
-  // last_reason_ to be set, but doesn't require the download to be in
-  // INTERRUPTED state.
-  virtual ResumeMode GetResumeMode() const;
-
   // State transition operations on regular downloads --------------------------
 
   // Start the download.
@@ -313,9 +300,6 @@
   // TODO(rdsmith): Unwind DownloadManagerImpl and DownloadItemImpl,
   // removing these from the public interface.
 
-  // Notify observers that this item is being removed by the user.
-  virtual void NotifyRemoved();
-
   virtual void OnDownloadedFileRemoved();
 
   // Provide a weak pointer reference to a DownloadDestinationObserver
@@ -613,6 +597,22 @@
   virtual void UpdateValidatorsOnResumption(
       const DownloadCreateInfo& new_create_info);
 
+  // Notify observers that this item is being removed by the user.
+  void NotifyRemoved();
+
+  enum ResumeMode {
+    RESUME_MODE_INVALID = 0,
+    RESUME_MODE_IMMEDIATE_CONTINUE,
+    RESUME_MODE_IMMEDIATE_RESTART,
+    RESUME_MODE_USER_CONTINUE,
+    RESUME_MODE_USER_RESTART
+  };
+
+  // Determines the resume mode for an interrupted download. Requires
+  // last_reason_ to be set, but doesn't require the download to be in
+  // INTERRUPTED state.
+  ResumeMode GetResumeMode() const;
+
   static DownloadState InternalToExternalState(
       DownloadInternalState internal_state);
   static DownloadInternalState ExternalToInternalState(
diff --git a/content/browser/download/mock_download_item_impl.h b/content/browser/download/mock_download_item_impl.h
index 5697238..33e4b45 100644
--- a/content/browser/download/mock_download_item_impl.h
+++ b/content/browser/download/mock_download_item_impl.h
@@ -117,7 +117,6 @@
   MOCK_CONST_METHOD0(GetWebContents, WebContents*());
   MOCK_CONST_METHOD0(GetFileNameToReportUser, base::FilePath());
   MOCK_METHOD1(SetDisplayName, void(const base::FilePath&));
-  MOCK_METHOD0(NotifyRemoved, void());
   // May be called when vlog is on.
   std::string DebugString(bool verbose) const override { return std::string(); }
 };
diff --git a/content/browser/frame_host/data_url_navigation_throttle.cc b/content/browser/frame_host/data_url_navigation_throttle.cc
index 60526be7..c29d29c2 100644
--- a/content/browser/frame_host/data_url_navigation_throttle.cc
+++ b/content/browser/frame_host/data_url_navigation_throttle.cc
@@ -7,11 +7,13 @@
 #include "base/feature_list.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/stringprintf.h"
+#include "build/build_config.h"
 #include "content/browser/frame_host/frame_tree.h"
 #include "content/browser/frame_host/frame_tree_node.h"
 #include "content/browser/frame_host/navigation_handle_impl.h"
 #include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_frame_host.h"
+#include "content/public/common/browser_side_navigation_policy.h"
 #include "content/public/common/console_message_level.h"
 #include "content/public/common/content_features.h"
 #include "url/url_constants.h"
@@ -31,6 +33,18 @@
 
 NavigationThrottle::ThrottleCheckResult
 DataUrlNavigationThrottle::WillProcessResponse() {
+#if defined(OS_ANDROID)
+  // This should ideally be done in CreateThrottleForNavigation(), but
+  // NavigationHandleImpl::GetRenderFrameHost() expects to not be run before
+  // WillProcessResponse().
+  // TODO(meacer): Remove this special case when PlzNavigate is enabled.
+  if (!IsBrowserSideNavigationEnabled() &&
+      navigation_handle()
+          ->GetRenderFrameHost()
+          ->IsDataUrlNavigationAllowedForAndroidWebView()) {
+    return PROCEED;
+  }
+#endif
   NavigationHandleImpl* handle =
       static_cast<NavigationHandleImpl*>(navigation_handle());
   if (handle->is_download())
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index 6f7126c..4eb65b14 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -1164,6 +1164,12 @@
       // only tildes. Until we understand that better, don't copy the cert in
       // this case.
       new_entry->GetSSL() = SSLStatus();
+
+      if (new_entry->GetURL().SchemeIs(url::kHttpsScheme)) {
+        UMA_HISTOGRAM_BOOLEAN(
+            "Navigation.SecureSchemeHasSSLStatus.NewPageInPageOriginMismatch",
+            !!new_entry->GetSSL().certificate);
+      }
     }
 
     // We expect |frame_entry| to be owned by |new_entry|.  This should never
@@ -1171,6 +1177,11 @@
     CHECK(frame_entry->HasOneRef());
 
     update_virtual_url = new_entry->update_virtual_url_with_url();
+
+    if (new_entry->GetURL().SchemeIs(url::kHttpsScheme)) {
+      UMA_HISTOGRAM_BOOLEAN("Navigation.SecureSchemeHasSSLStatus.NewPageInPage",
+                            !!new_entry->GetSSL().certificate);
+    }
   }
 
   // Only make a copy of the pending entry if it is appropriate for the new page
@@ -1190,6 +1201,12 @@
 
     update_virtual_url = new_entry->update_virtual_url_with_url();
     new_entry->GetSSL() = handle->ssl_status();
+
+    if (new_entry->GetURL().SchemeIs(url::kHttpsScheme)) {
+      UMA_HISTOGRAM_BOOLEAN(
+          "Navigation.SecureSchemeHasSSLStatus.NewPagePendingEntryMatches",
+          !!new_entry->GetSSL().certificate);
+    }
   }
 
   // For non-in-page commits with no matching pending entry, create a new entry.
@@ -1211,6 +1228,12 @@
     // the URL.
     update_virtual_url = needs_update;
     new_entry->GetSSL() = handle->ssl_status();
+
+    if (new_entry->GetURL().SchemeIs(url::kHttpsScheme)) {
+      UMA_HISTOGRAM_BOOLEAN(
+          "Navigation.SecureSchemeHasSSLStatus.NewPageNoMatchingEntry",
+          !!new_entry->GetSSL().certificate);
+    }
   }
 
   // Don't use the page type from the pending entry. Some interstitial page
@@ -1283,6 +1306,21 @@
     // NavigationHandle so don't overwrite the existing entry's SSLStatus.
     if (!is_same_document)
       entry->GetSSL() = handle->ssl_status();
+
+    if (entry->GetURL().SchemeIs(url::kHttpsScheme)) {
+      bool has_cert = !!entry->GetSSL().certificate;
+      if (is_same_document) {
+        UMA_HISTOGRAM_BOOLEAN(
+            "Navigation.SecureSchemeHasSSLStatus."
+            "ExistingPageSameDocumentIntendedAsNew",
+            has_cert);
+      } else {
+        UMA_HISTOGRAM_BOOLEAN(
+            "Navigation.SecureSchemeHasSSLStatus."
+            "ExistingPageDifferentDocumentIntendedAsNew",
+            has_cert);
+      }
+    }
   } else if (params.nav_entry_id) {
     // This is a browser-initiated navigation (back/forward/reload).
     entry = GetEntryWithUniqueID(params.nav_entry_id);
@@ -1307,6 +1345,30 @@
       if (was_restored)
         entry->GetSSL() = handle->ssl_status();
     }
+
+    if (entry->GetURL().SchemeIs(url::kHttpsScheme)) {
+      bool has_cert = !!entry->GetSSL().certificate;
+      if (is_same_document && was_restored) {
+        UMA_HISTOGRAM_BOOLEAN(
+            "Navigation.SecureSchemeHasSSLStatus."
+            "ExistingPageSameDocumentRestoredBrowserInitiated",
+            has_cert);
+      } else if (is_same_document && !was_restored) {
+        UMA_HISTOGRAM_BOOLEAN(
+            "Navigation.SecureSchemeHasSSLStatus."
+            "ExistingPageSameDocumentBrowserInitiated",
+            has_cert);
+      } else if (!is_same_document && was_restored) {
+        UMA_HISTOGRAM_BOOLEAN(
+            "Navigation.SecureSchemeHasSSLStatus."
+            "ExistingPageRestoredBrowserInitiated",
+            has_cert);
+      } else {
+        UMA_HISTOGRAM_BOOLEAN(
+            "Navigation.SecureSchemeHasSSLStatus.ExistingPageBrowserInitiated",
+            has_cert);
+      }
+    }
   } else {
     // This is renderer-initiated. The only kinds of renderer-initated
     // navigations that are EXISTING_PAGE are reloads and location.replace,
@@ -1317,6 +1379,21 @@
     // NavigationHandle so don't overwrite the existing entry's SSLStatus.
     if (!is_same_document)
       entry->GetSSL() = handle->ssl_status();
+
+    if (entry->GetURL().SchemeIs(url::kHttpsScheme)) {
+      bool has_cert = !!entry->GetSSL().certificate;
+      if (is_same_document) {
+        UMA_HISTOGRAM_BOOLEAN(
+            "Navigation.SecureSchemeHasSSLStatus."
+            "ExistingPageSameDocumentRendererInitiated",
+            has_cert);
+      } else {
+        UMA_HISTOGRAM_BOOLEAN(
+            "Navigation.SecureSchemeHasSSLStatus."
+            "ExistingPageDifferentDocumentRendererInitiated",
+            has_cert);
+      }
+    }
   }
   DCHECK(entry);
 
@@ -1394,6 +1471,11 @@
   // update the SSL status.
   existing_entry->GetSSL() = handle->ssl_status();
 
+  if (existing_entry->GetURL().SchemeIs(url::kHttpsScheme)) {
+    UMA_HISTOGRAM_BOOLEAN("Navigation.SecureSchemeHasSSLStatus.SamePage",
+                          !!existing_entry->GetSSL().certificate);
+  }
+
   // The extra headers may have changed due to reloading with different headers.
   existing_entry->set_extra_headers(pending_entry_->extra_headers());
 
@@ -1433,6 +1515,11 @@
           frame_entry.get(), is_same_document, rfh->frame_tree_node(),
           delegate_->GetFrameTree()->root());
 
+  if (new_entry->GetURL().SchemeIs(url::kHttpsScheme)) {
+    UMA_HISTOGRAM_BOOLEAN("Navigation.SecureSchemeHasSSLStatus.NewSubFrame",
+                          !!new_entry->GetSSL().certificate);
+  }
+
   // TODO(creis): Update this to add the frame_entry if we can't find the one
   // to replace, which can happen due to a unique name change.  See
   // https://crbug.com/607205.  For now, frame_entry will be deleted when it
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index fd98c05..4c6e99c 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -169,10 +169,16 @@
 // The next value to use for the javascript callback id.
 int g_next_javascript_callback_id = 1;
 
+#if defined(OS_ANDROID)
 // Whether to allow injecting javascript into any kind of frame (for Android
 // WebView).
 bool g_allow_injecting_javascript = false;
 
+// Whether to allow data URL navigations for Android WebView.
+// TODO(meacer): Remove after PlzNavigate ships.
+bool g_allow_data_url_navigation = false;
+#endif
+
 // The (process id, routing id) pair that identifies one RenderFrame.
 typedef std::pair<int32_t, int32_t> RenderFrameHostID;
 typedef base::hash_map<RenderFrameHostID, RenderFrameHostImpl*>
@@ -378,6 +384,16 @@
   g_allow_injecting_javascript = true;
 }
 
+// static
+void RenderFrameHost::AllowDataUrlNavigationForAndroidWebView() {
+  g_allow_data_url_navigation = true;
+}
+
+// static
+bool RenderFrameHost::IsDataUrlNavigationAllowedForAndroidWebView() {
+  return g_allow_data_url_navigation;
+}
+
 void CreateMediaPlayerRenderer(
     content::RenderFrameHost* render_frame_host,
     const service_manager::BindSourceInfo& source_info,
@@ -3775,8 +3791,11 @@
 }
 
 bool RenderFrameHostImpl::CanExecuteJavaScript() {
-  return g_allow_injecting_javascript ||
-         !frame_tree_node_->current_url().is_valid() ||
+#if defined(OS_ANDROID)
+  if (g_allow_injecting_javascript)
+    return true;
+#endif
+  return !frame_tree_node_->current_url().is_valid() ||
          frame_tree_node_->current_url().SchemeIs(kChromeDevToolsScheme) ||
          ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
              GetProcess()->GetID()) ||
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.cc b/content/browser/frame_host/render_widget_host_view_child_frame.cc
index df454073..6d0da4a6 100644
--- a/content/browser/frame_host/render_widget_host_view_child_frame.cc
+++ b/content/browser/frame_host/render_widget_host_view_child_frame.cc
@@ -15,11 +15,11 @@
 #include "build/build_config.h"
 #include "cc/output/copy_output_request.h"
 #include "cc/output/copy_output_result.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
 #include "cc/surfaces/frame_sink_manager.h"
 #include "cc/surfaces/surface.h"
 #include "cc/surfaces/surface_manager.h"
 #include "components/viz/host/host_frame_sink_manager.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "content/browser/accessibility/browser_accessibility_manager.h"
 #include "content/browser/browser_plugin/browser_plugin_guest.h"
 #include "content/browser/compositor/surface_utils.h"
@@ -833,7 +833,7 @@
   constexpr bool is_root = false;
   constexpr bool handles_frame_sink_id_invalidation = false;
   constexpr bool needs_sync_points = true;
-  support_ = cc::CompositorFrameSinkSupport::Create(
+  support_ = viz::CompositorFrameSinkSupport::Create(
       this, GetFrameSinkManager(), frame_sink_id_, is_root,
       handles_frame_sink_id_invalidation, needs_sync_points);
   if (parent_frame_sink_id_.is_valid()) {
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame.h b/content/browser/frame_host/render_widget_host_view_child_frame.h
index 633b6c4..89a7967 100644
--- a/content/browser/frame_host/render_widget_host_view_child_frame.h
+++ b/content/browser/frame_host/render_widget_host_view_child_frame.h
@@ -18,9 +18,9 @@
 #include "build/build_config.h"
 #include "cc/resources/returned_resource.h"
 #include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
 #include "cc/surfaces/surface_info.h"
 #include "cc/surfaces/surface_sequence.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h"
 #include "content/browser/compositor/image_transport_factory.h"
 #include "content/browser/renderer_host/event_with_latency_info.h"
 #include "content/browser/renderer_host/render_widget_host_view_base.h"
@@ -31,7 +31,7 @@
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/native_widget_types.h"
 
-namespace cc {
+namespace viz {
 class CompositorFrameSinkSupport;
 }
 
@@ -54,7 +54,7 @@
 class CONTENT_EXPORT RenderWidgetHostViewChildFrame
     : public RenderWidgetHostViewBase,
       public TouchSelectionControllerClientManager::Observer,
-      public NON_EXPORTED_BASE(cc::CompositorFrameSinkSupportClient) {
+      public NON_EXPORTED_BASE(viz::CompositorFrameSinkSupportClient) {
  public:
   static RenderWidgetHostViewChildFrame* Create(RenderWidgetHost* widget);
   ~RenderWidgetHostViewChildFrame() override;
@@ -171,7 +171,7 @@
   BrowserAccessibilityManager* CreateBrowserAccessibilityManager(
       BrowserAccessibilityDelegate* delegate, bool for_root_frame) override;
 
-  // cc::CompositorFrameSinkSupportClient implementation.
+  // viz::CompositorFrameSinkSupportClient implementation.
   void DidReceiveCompositorFrameAck(
       const std::vector<cc::ReturnedResource>& resources) override;
   void OnBeginFrame(const cc::BeginFrameArgs& args) override;
@@ -241,7 +241,7 @@
   viz::FrameSinkId frame_sink_id_;
 
   // Surface-related state.
-  std::unique_ptr<cc::CompositorFrameSinkSupport> support_;
+  std::unique_ptr<viz::CompositorFrameSinkSupport> support_;
   viz::LocalSurfaceId local_surface_id_;
   uint32_t next_surface_sequence_;
   gfx::Size current_surface_size_;
diff --git a/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc b/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc
index ce5e699..2028114 100644
--- a/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc
+++ b/content/browser/frame_host/render_widget_host_view_child_frame_unittest.cc
@@ -15,12 +15,12 @@
 #include "base/test/scoped_task_environment.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "build/build_config.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
 #include "cc/surfaces/surface.h"
 #include "cc/surfaces/surface_manager.h"
 #include "cc/surfaces/surface_sequence.h"
 #include "cc/test/begin_frame_args_test.h"
 #include "cc/test/fake_external_begin_frame_source.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
 #include "content/browser/frame_host/cross_process_frame_connector.h"
 #include "content/browser/gpu/compositor_util.h"
diff --git a/content/browser/media/media_internals.cc b/content/browser/media/media_internals.cc
index d5482d90..d0da233 100644
--- a/content/browser/media/media_internals.cc
+++ b/content/browser/media/media_internals.cc
@@ -785,6 +785,10 @@
     : can_update_(false),
       owner_ids_(),
       uma_handler_(new MediaInternalsUMAHandler(this)) {
+  // TODO(sandersd): Is there ever a relevant case where TERMINATED is sent
+  // without CLOSED also being sent?
+  registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_CLOSED,
+                 NotificationService::AllBrowserContextsAndSources());
   registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED,
                  NotificationService::AllBrowserContextsAndSources());
 }
@@ -795,10 +799,9 @@
                              const NotificationSource& source,
                              const NotificationDetails& details) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  DCHECK_EQ(type, NOTIFICATION_RENDERER_PROCESS_TERMINATED);
   RenderProcessHost* process = Source<RenderProcessHost>(source).ptr();
-
   uma_handler_->OnProcessTerminated(process->GetID());
+  // TODO(sandersd): Send a termination event before clearing the log.
   saved_events_by_process_.erase(process->GetID());
 }
 
diff --git a/content/browser/media/media_internals_proxy.cc b/content/browser/media/media_internals_proxy.cc
index 5b62036..f7a87f9 100644
--- a/content/browser/media/media_internals_proxy.cc
+++ b/content/browser/media/media_internals_proxy.cc
@@ -4,40 +4,18 @@
 
 #include "content/browser/media/media_internals_proxy.h"
 
-#include <stddef.h>
-
-#include <utility>
-
 #include "base/bind.h"
-#include "base/bind_helpers.h"
 #include "base/location.h"
-#include "base/macros.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
+#include "content/browser/media/media_internals.h"
 #include "content/browser/media/media_internals_handler.h"
-#include "content/public/browser/content_browser_client.h"
-#include "content/public/browser/notification_service.h"
-#include "content/public/browser/notification_types.h"
-#include "content/public/browser/render_process_host.h"
-#include "content/public/browser/web_ui.h"
+#include "content/public/browser/browser_thread.h"
 
 namespace content {
 
 MediaInternalsProxy::MediaInternalsProxy() {
-  registrar_.Add(this, NOTIFICATION_RENDERER_PROCESS_TERMINATED,
-                 NotificationService::AllBrowserContextsAndSources());
 }
 
-void MediaInternalsProxy::Observe(int type,
-                                  const NotificationSource& source,
-                                  const NotificationDetails& details) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  DCHECK_EQ(type, NOTIFICATION_RENDERER_PROCESS_TERMINATED);
-  RenderProcessHost* process = Source<RenderProcessHost>(source).ptr();
-  CallJavaScriptFunctionOnUIThread(
-      "media.onRendererTerminated",
-      base::MakeUnique<base::Value>(process->GetID()));
-}
+MediaInternalsProxy::~MediaInternalsProxy() {}
 
 void MediaInternalsProxy::Attach(MediaInternalsMessageHandler* handler) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -65,8 +43,6 @@
       base::Bind(&MediaInternalsProxy::GetEverythingOnIOThread, this));
 }
 
-MediaInternalsProxy::~MediaInternalsProxy() {}
-
 void MediaInternalsProxy::GetEverythingOnIOThread() {
   DCHECK_CURRENTLY_ON(BrowserThread::IO);
   // TODO(xhwang): Investigate whether we can update on UI thread directly.
@@ -81,14 +57,4 @@
     handler_->OnUpdate(update);
 }
 
-void MediaInternalsProxy::CallJavaScriptFunctionOnUIThread(
-    const std::string& function,
-    std::unique_ptr<base::Value> args) {
-  DCHECK_CURRENTLY_ON(BrowserThread::UI);
-  std::vector<const base::Value*> args_vector;
-  args_vector.push_back(args.get());
-  base::string16 update = WebUI::GetJavascriptCall(function, args_vector);
-  UpdateUIOnUIThread(update);
-}
-
 }  // namespace content
diff --git a/content/browser/media/media_internals_proxy.h b/content/browser/media/media_internals_proxy.h
index 47b7db4d..338c3e67 100644
--- a/content/browser/media/media_internals_proxy.h
+++ b/content/browser/media/media_internals_proxy.h
@@ -5,19 +5,12 @@
 #ifndef CONTENT_BROWSER_MEDIA_MEDIA_INTERNALS_PROXY_H_
 #define CONTENT_BROWSER_MEDIA_MEDIA_INTERNALS_PROXY_H_
 
-#include <memory>
-
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/sequenced_task_runner_helpers.h"
+#include "base/strings/string16.h"
 #include "content/browser/media/media_internals.h"
 #include "content/public/browser/browser_thread.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-
-namespace base {
-class Value;
-}  // namespace base
 
 namespace content {
 class MediaInternalsMessageHandler;
@@ -28,16 +21,10 @@
 // threads before destruction.
 class MediaInternalsProxy
     : public base::RefCountedThreadSafe<MediaInternalsProxy,
-                                        BrowserThread::DeleteOnUIThread>,
-      public NotificationObserver {
+                                        BrowserThread::DeleteOnUIThread> {
  public:
   MediaInternalsProxy();
 
-  // NotificationObserver implementation.
-  void Observe(int type,
-               const NotificationSource& source,
-               const NotificationDetails& details) override;
-
   // Register a Handler and start receiving callbacks from MediaInternals.
   void Attach(MediaInternalsMessageHandler* handler);
 
@@ -50,19 +37,14 @@
  private:
   friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
   friend class base::DeleteHelper<MediaInternalsProxy>;
-  ~MediaInternalsProxy() override;
+  virtual ~MediaInternalsProxy();
 
   void GetEverythingOnIOThread();
 
   // Callback for MediaInternals to update. Must be called on UI thread.
   void UpdateUIOnUIThread(const base::string16& update);
 
-  // Call a JavaScript function on the page.
-  void CallJavaScriptFunctionOnUIThread(const std::string& function,
-                                        std::unique_ptr<base::Value> args);
-
   MediaInternalsMessageHandler* handler_;
-  NotificationRegistrar registrar_;
   MediaInternals::UpdateCallback update_callback_;
 
   DISALLOW_COPY_AND_ASSIGN(MediaInternalsProxy);
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index 5a8eb8ed..c8a5720e 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -40,16 +40,16 @@
 #include "cc/output/vulkan_in_process_context_provider.h"
 #include "cc/raster/single_thread_task_graph_runner.h"
 #include "cc/resources/ui_resource_manager.h"
-#include "cc/surfaces/direct_layer_tree_frame_sink.h"
-#include "cc/surfaces/display.h"
-#include "cc/surfaces/display_scheduler.h"
 #include "cc/trees/layer_tree_host.h"
 #include "cc/trees/layer_tree_settings.h"
 #include "components/viz/common/frame_sink_id_allocator.h"
 #include "components/viz/common/gl_helper.h"
 #include "components/viz/host/host_frame_sink_manager.h"
+#include "components/viz/service/display/display.h"
+#include "components/viz/service/display/display_scheduler.h"
 #include "components/viz/service/display_embedder/compositor_overlay_candidate_validator_android.h"
 #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h"
+#include "components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h"
 #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h"
 #include "content/browser/browser_main_loop.h"
 #include "content/browser/compositor/surface_utils.h"
@@ -790,7 +790,7 @@
     return;
   }
 
-  // Unretained is safe this owns cc::Display which owns OutputSurface.
+  // Unretained is safe this owns viz::Display which owns OutputSurface.
   auto display_output_surface = base::MakeUnique<AndroidOutputSurface>(
       context_provider,
       base::Bind(&CompositorImpl::DidSwapBuffers, base::Unretained(this)));
@@ -815,9 +815,9 @@
 
   cc::FrameSinkManager* manager = GetFrameSinkManager();
   auto* task_runner = base::ThreadTaskRunnerHandle::Get().get();
-  std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler(
+  auto scheduler = base::MakeUnique<viz::DisplayScheduler>(
       root_window_->GetBeginFrameSource(), task_runner,
-      display_output_surface->capabilities().max_frames_pending));
+      display_output_surface->capabilities().max_frames_pending);
 
   cc::RendererSettings renderer_settings;
   renderer_settings.allow_antialiasing = false;
@@ -827,18 +827,18 @@
   auto* gpu_memory_buffer_manager = BrowserMainLoop::GetInstance()
                                         ->gpu_channel_establish_factory()
                                         ->GetGpuMemoryBufferManager();
-  display_.reset(new cc::Display(
+  display_ = base::MakeUnique<viz::Display>(
       viz::ServerSharedBitmapManager::current(), gpu_memory_buffer_manager,
       renderer_settings, frame_sink_id_, std::move(display_output_surface),
       std::move(scheduler),
-      base::MakeUnique<cc::TextureMailboxDeleter>(task_runner)));
+      base::MakeUnique<cc::TextureMailboxDeleter>(task_runner));
 
   auto layer_tree_frame_sink =
       vulkan_context_provider
-          ? base::MakeUnique<cc::DirectLayerTreeFrameSink>(
+          ? base::MakeUnique<viz::DirectLayerTreeFrameSink>(
                 frame_sink_id_, manager, display_.get(),
                 vulkan_context_provider)
-          : base::MakeUnique<cc::DirectLayerTreeFrameSink>(
+          : base::MakeUnique<viz::DirectLayerTreeFrameSink>(
                 frame_sink_id_, manager, display_.get(), context_provider,
                 nullptr /* worker_context_provider */,
                 gpu_memory_buffer_manager,
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h
index 5f01a53..83e25f0 100644
--- a/content/browser/renderer_host/compositor_impl_android.h
+++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -33,7 +33,6 @@
 
 namespace cc {
 class AnimationHost;
-class Display;
 class FrameSinkId;
 class FrameSinkManager;
 class Layer;
@@ -43,6 +42,7 @@
 }
 
 namespace viz {
+class Display;
 class HostFrameSinkManager;
 }
 
@@ -154,7 +154,7 @@
   std::unique_ptr<cc::LayerTreeHost> host_;
   ui::ResourceManagerImpl resource_manager_;
 
-  std::unique_ptr<cc::Display> display_;
+  std::unique_ptr<viz::Display> display_;
 
   gfx::ColorSpace display_color_space_;
   gfx::Size size_;
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc
index ce7e0dda..541a797a 100644
--- a/content/browser/renderer_host/delegated_frame_host.cc
+++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -17,12 +17,12 @@
 #include "cc/output/compositor_frame.h"
 #include "cc/output/copy_output_request.h"
 #include "cc/resources/single_release_callback.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
 #include "cc/surfaces/frame_sink_manager.h"
 #include "cc/surfaces/surface.h"
 #include "cc/surfaces/surface_hittest.h"
 #include "components/viz/common/gl_helper.h"
 #include "components/viz/common/quads/texture_mailbox.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "content/browser/compositor/surface_utils.h"
 #include "content/browser/gpu/compositor_util.h"
 #include "content/browser/renderer_host/compositor_resize_lock.h"
@@ -843,7 +843,7 @@
   constexpr bool handles_frame_sink_id_invalidation = false;
   constexpr bool needs_sync_points = true;
   ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
-  support_ = cc::CompositorFrameSinkSupport::Create(
+  support_ = viz::CompositorFrameSinkSupport::Create(
       this, factory->GetContextFactoryPrivate()->GetFrameSinkManager(),
       frame_sink_id_, is_root, handles_frame_sink_id_invalidation,
       needs_sync_points);
diff --git a/content/browser/renderer_host/delegated_frame_host.h b/content/browser/renderer_host/delegated_frame_host.h
index c819b09..875445c 100644
--- a/content/browser/renderer_host/delegated_frame_host.h
+++ b/content/browser/renderer_host/delegated_frame_host.h
@@ -13,7 +13,7 @@
 #include "cc/output/begin_frame_args.h"
 #include "cc/output/copy_output_result.h"
 #include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h"
 #include "components/viz/service/frame_sinks/frame_evictor.h"
 #include "content/browser/compositor/image_transport_factory.h"
 #include "content/browser/compositor/owned_mailbox.h"
@@ -33,15 +33,12 @@
 class TickClock;
 }
 
-namespace cc {
-class CompositorFrameSinkSupport;
-}
-
 namespace media {
 class VideoFrame;
 }
 
 namespace viz {
+class CompositorFrameSinkSupport;
 class ReadbackYUVInterface;
 }
 
@@ -83,7 +80,7 @@
       public ui::CompositorVSyncManager::Observer,
       public ui::ContextFactoryObserver,
       public viz::FrameEvictorClient,
-      public NON_EXPORTED_BASE(cc::CompositorFrameSinkSupportClient),
+      public NON_EXPORTED_BASE(viz::CompositorFrameSinkSupportClient),
       public base::SupportsWeakPtr<DelegatedFrameHost> {
  public:
   DelegatedFrameHost(const viz::FrameSinkId& frame_sink_id,
@@ -108,7 +105,7 @@
   // FrameEvictorClient implementation.
   void EvictDelegatedFrame() override;
 
-  // cc::CompositorFrameSinkSupportClient implementation.
+  // viz::CompositorFrameSinkSupportClient implementation.
   void DidReceiveCompositorFrameAck(
       const std::vector<cc::ReturnedResource>& resources) override;
   void OnBeginFrame(const cc::BeginFrameArgs& args) override;
@@ -280,7 +277,7 @@
   SkColor background_color_;
 
   // State for rendering into a Surface.
-  std::unique_ptr<cc::CompositorFrameSinkSupport> support_;
+  std::unique_ptr<viz::CompositorFrameSinkSupport> support_;
   gfx::Size current_surface_size_;
   float current_scale_factor_;
   std::vector<cc::ReturnedResource> surface_returned_resources_;
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 3d2a044..603e923a 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -1200,6 +1200,17 @@
   surface_returned_resources_.clear();
 }
 
+void RenderWidgetHostViewAndroid::EvictFrameIfNecessary() {
+  if (host_->delegate()->IsFullscreenForCurrentTab() &&
+      current_surface_size_ != view_.GetPhysicalBackingSize()) {
+    // When we're in a fullscreen and the frame size doesn't match the view
+    // size (e.g. during a fullscreen rotation), we show black instead of the
+    // incorrectly-sized frame.
+    EvictDelegatedFrame();
+    UpdateBackgroundColor(SK_ColorBLACK);
+  }
+}
+
 void RenderWidgetHostViewAndroid::SubmitCompositorFrame(
     const viz::LocalSurfaceId& local_surface_id,
     cc::CompositorFrame frame) {
@@ -1259,6 +1270,7 @@
 
   frame_evictor_->DiscardedFrame();
   delegated_frame_host_->DestroyDelegatedContent();
+  current_surface_size_.SetSize(0, 0);
 }
 
 void RenderWidgetHostViewAndroid::OnDidNotProduceFrame(
@@ -1519,6 +1531,8 @@
                      frame_metadata.max_page_scale_factor),
       frame_metadata.root_layer_size, frame_metadata.scrollable_viewport_size,
       top_content_offset, top_shown_pix, top_changed, is_mobile_optimized);
+
+  EvictFrameIfNecessary();
 }
 
 void RenderWidgetHostViewAndroid::ShowInternal() {
@@ -2143,6 +2157,7 @@
 }
 
 void RenderWidgetHostViewAndroid::OnPhysicalBackingSizeChanged() {
+  EvictFrameIfNecessary();
   WasResized();
 }
 
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index e6db3f7..0f717a4 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -332,6 +332,8 @@
 
   void UpdateBackgroundColor(SkColor color);
 
+  void EvictFrameIfNecessary();
+
   // DevTools ScreenCast support for Android WebView.
   void SynchronousCopyContents(const gfx::Rect& src_subrect_in_pixel,
                                const gfx::Size& dst_size_in_pixel,
diff --git a/content/browser/resources/media/main.js b/content/browser/resources/media/main.js
index 65bbaca..e6c9d8c 100644
--- a/content/browser/resources/media/main.js
+++ b/content/browser/resources/media/main.js
@@ -27,14 +27,6 @@
     manager.updateVideoCaptureCapabilities(videoCaptureCapabilities)
   }
 
-  media.onRendererTerminated = function(renderId) {
-    util.object.forEach(manager.players_, function(playerInfo, id) {
-      if (playerInfo.properties['render_id'] == renderId) {
-        manager.removePlayer(id);
-      }
-    });
-  };
-
   media.updateAudioComponent = function(component) {
     var uniqueComponentId = component.owner_id + ':' + component.component_id;
     switch (component.status) {
diff --git a/content/browser/service_manager/common_browser_interfaces.cc b/content/browser/service_manager/common_browser_interfaces.cc
index c88fd30..645af99 100644
--- a/content/browser/service_manager/common_browser_interfaces.cc
+++ b/content/browser/service_manager/common_browser_interfaces.cc
@@ -15,6 +15,7 @@
 #include "content/browser/browser_main_loop.h"
 #include "content/public/common/connection_filter.h"
 #include "content/public/common/service_manager_connection.h"
+#include "device/geolocation/geolocation_config.h"
 #include "mojo/public/cpp/bindings/interface_request.h"
 #include "services/resource_coordinator/memory_instrumentation/coordinator_impl.h"
 #include "services/service_manager/public/cpp/binder_registry.h"
@@ -35,6 +36,7 @@
  public:
   ConnectionFilterImpl()
       : main_thread_task_runner_(base::ThreadTaskRunnerHandle::Get()) {
+    RegisterMainThreadInterface(base::Bind(&device::GeolocationConfig::Create));
     RegisterMainThreadInterface(base::Bind(&BindMemoryCoordinatorRequest));
 
     auto* browser_main_loop = BrowserMainLoop::GetInstance();
diff --git a/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java b/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java
index 261658a..c0e89d1 100644
--- a/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java
@@ -70,7 +70,12 @@
         // Register to get token updates.  Note that this may not call us back directly, since
         // |mDialogCore| hasn't been initialized yet.
         mNativeHandle = nativeInit(config.routingToken.high, config.routingToken.low);
-        assert mNativeHandle != 0;
+
+        if (mNativeHandle == 0) {
+            mClient.onDestroyed();
+            cleanup();
+            return;
+        }
 
         // Post init to the overlay thread.
         final DialogOverlayCore dialogCore = mDialogCore;
@@ -206,13 +211,15 @@
     private void sendWindowTokenToCore(final IBinder token) {
         ThreadUtils.assertOnUiThread();
 
-        final DialogOverlayCore dialogCore = mDialogCore;
-        mOverlayHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                dialogCore.onWindowToken(token);
-            }
-        });
+        if (mDialogCore != null) {
+            final DialogOverlayCore dialogCore = mDialogCore;
+            mOverlayHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    dialogCore.onWindowToken(token);
+                }
+            });
+        }
     }
 
     /**
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTest.java b/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTest.java
index ab8e1595..14fc1bee 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/androidoverlay/DialogOverlayImplTest.java
@@ -59,6 +59,42 @@
 
     @SmallTest
     @Feature({"AndroidOverlay"})
+    public void testCreateOverlayFailsIfWebContentsHidden() {
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                getWebContents().onHide();
+            }
+        });
+
+        DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
+        Assert.assertNotNull(overlay);
+
+        // We should be notified that the overlay is destroyed.
+        Client.Event event = getClient().nextEvent();
+        Assert.assertEquals(Client.DESTROYED, event.which);
+    }
+
+    @SmallTest
+    @Feature({"AndroidOverlay"})
+    public void testHiddingWebContentsDestroysOverlay() {
+        DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
+        Assert.assertNotNull(overlay);
+
+        ThreadUtils.runOnUiThreadBlocking(new Runnable() {
+            @Override
+            public void run() {
+                getWebContents().onHide();
+            }
+        });
+
+        // We should be notified that the overlay is destroyed.
+        Client.Event event = getClient().nextEvent();
+        Assert.assertEquals(Client.DESTROYED, event.which);
+    }
+
+    @SmallTest
+    @Feature({"AndroidOverlay"})
     public void testScheduleLayoutDoesntCrash() {
         // Make sure that we don't get any messages due to scheduleLayout, and we don't crash.
         final DialogOverlayImpl overlay = createOverlay(0, 0, 10, 10);
diff --git a/content/public/app/mojo/content_browser_manifest.json b/content/public/app/mojo/content_browser_manifest.json
index ab5e08d..124d48e 100644
--- a/content/public/app/mojo/content_browser_manifest.json
+++ b/content/public/app/mojo/content_browser_manifest.json
@@ -46,6 +46,9 @@
           "shape_detection::mojom::TextDetection",
           "ui::mojom::Gpu"
         ],
+        "geolocation_config": [
+          "device::mojom::GeolocationConfig"
+        ],
         "service_manager:service_factory": [
           "service_manager::mojom::ServiceFactory"
         ],
@@ -57,7 +60,13 @@
       "requires": {
         "*": [ "app" ],
         // In classic ash, the browser supplies ash interfaces to itself.
-        "content_browser": [ "ash", "display", "memory_instrumentation", "url_keyed_metrics" ],
+        "content_browser": [
+          "ash",
+          "display",
+          "memory_instrumentation",
+          "url_keyed_metrics",
+          "geolocation_config"
+        ],
         "content_gpu": [ "browser" ],
         "content_plugin": [ "browser" ],
         "content_renderer": [ "browser" ],
diff --git a/content/public/browser/render_frame_host.h b/content/public/browser/render_frame_host.h
index 4bcf78b6..c155b229 100644
--- a/content/public/browser/render_frame_host.h
+++ b/content/public/browser/render_frame_host.h
@@ -66,6 +66,11 @@
   // is present only to support Android WebView and must not be used in other
   // configurations.
   static void AllowInjectingJavaScriptForAndroidWebView();
+
+  // Temporary hack to enable data URLs on Android Webview until PlzNavigate
+  // ships.
+  static void AllowDataUrlNavigationForAndroidWebView();
+  static bool IsDataUrlNavigationAllowedForAndroidWebView();
 #endif
 
   // Returns a RenderFrameHost given its accessibility tree ID.
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn
index ca2c49f..f2d244474 100644
--- a/content/renderer/BUILD.gn
+++ b/content/renderer/BUILD.gn
@@ -444,6 +444,7 @@
     "//components/url_formatter",
     "//components/variations",
     "//components/viz/client",
+    "//components/viz/service",
     "//content:resources",
     "//content/child",
     "//content/common",
diff --git a/content/renderer/android/DEPS b/content/renderer/android/DEPS
index bec0ab9..3f8f3da 100644
--- a/content/renderer/android/DEPS
+++ b/content/renderer/android/DEPS
@@ -1,3 +1,5 @@
 include_rules = [
+  "+components/viz/service/display",
+  "+components/viz/service/frame_sinks",
   "+third_party/libphonenumber",  # For phone number detection.
 ]
diff --git a/content/renderer/android/synchronous_layer_tree_frame_sink.cc b/content/renderer/android/synchronous_layer_tree_frame_sink.cc
index 7998397..9137958f 100644
--- a/content/renderer/android/synchronous_layer_tree_frame_sink.cc
+++ b/content/renderer/android/synchronous_layer_tree_frame_sink.cc
@@ -23,10 +23,10 @@
 #include "cc/output/texture_mailbox_deleter.h"
 #include "cc/quads/render_pass.h"
 #include "cc/quads/surface_draw_quad.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
-#include "cc/surfaces/display.h"
 #include "cc/surfaces/frame_sink_manager.h"
 #include "components/viz/common/local_surface_id_allocator.h"
+#include "components/viz/service/display/display.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "content/common/android/sync_compositor_messages.h"
 #include "content/common/view_messages.h"
 #include "content/renderer/android/synchronous_compositor_filter.h"
@@ -176,10 +176,10 @@
   constexpr bool child_support_is_root = false;
   constexpr bool handles_frame_sink_id_invalidation = true;
   constexpr bool needs_sync_points = true;
-  root_support_ = cc::CompositorFrameSinkSupport::Create(
+  root_support_ = viz::CompositorFrameSinkSupport::Create(
       this, frame_sink_manager_.get(), kRootFrameSinkId, root_support_is_root,
       handles_frame_sink_id_invalidation, needs_sync_points);
-  child_support_ = cc::CompositorFrameSinkSupport::Create(
+  child_support_ = viz::CompositorFrameSinkSupport::Create(
       this, frame_sink_manager_.get(), kChildFrameSinkId, child_support_is_root,
       handles_frame_sink_id_invalidation, needs_sync_points);
 
@@ -196,10 +196,10 @@
   // resources.
   // TODO(crbug.com/692814): The Display never sends its resources out of
   // process so there is no reason for it to use a SharedBitmapManager.
-  display_.reset(new cc::Display(
+  display_ = base::MakeUnique<viz::Display>(
       shared_bitmap_manager_, nullptr /* gpu_memory_buffer_manager */,
       software_renderer_settings, kRootFrameSinkId, std::move(output_surface),
-      nullptr /* scheduler */, nullptr /* texture_mailbox_deleter */));
+      nullptr /* scheduler */, nullptr /* texture_mailbox_deleter */);
   display_->Initialize(&display_client_,
                        frame_sink_manager_->surface_manager());
   display_->SetVisible(true);
diff --git a/content/renderer/android/synchronous_layer_tree_frame_sink.h b/content/renderer/android/synchronous_layer_tree_frame_sink.h
index e10a164..2f9ab551 100644
--- a/content/renderer/android/synchronous_layer_tree_frame_sink.h
+++ b/content/renderer/android/synchronous_layer_tree_frame_sink.h
@@ -18,8 +18,8 @@
 #include "cc/output/compositor_frame.h"
 #include "cc/output/layer_tree_frame_sink.h"
 #include "cc/output/managed_memory_policy.h"
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
-#include "cc/surfaces/display_client.h"
+#include "components/viz/service/display/display_client.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h"
 #include "ipc/ipc_message.h"
 #include "ui/gfx/transform.h"
 
@@ -27,9 +27,7 @@
 
 namespace cc {
 class BeginFrameSource;
-class CompositorFrameSinkSupport;
 class ContextProvider;
-class Display;
 class FrameSinkManager;
 }  // namespace cc
 
@@ -39,8 +37,10 @@
 }  // namespace IPC
 
 namespace viz {
+class CompositorFrameSinkSupport;
+class Display;
 class LocalSurfaceIdAllocator;
-}
+}  // namespace viz
 
 namespace content {
 
@@ -68,7 +68,7 @@
 // to a fixed thread when BindToClient is called.
 class SynchronousLayerTreeFrameSink
     : NON_EXPORTED_BASE(public cc::LayerTreeFrameSink),
-      public cc::CompositorFrameSinkSupportClient {
+      public viz::CompositorFrameSinkSupportClient {
  public:
   SynchronousLayerTreeFrameSink(
       scoped_refptr<cc::ContextProvider> context_provider,
@@ -98,7 +98,7 @@
                     const gfx::Transform& transform_for_tile_priority);
   void DemandDrawSw(SkCanvas* canvas);
 
-  // CompositorFrameSinkSupportClient implementation.
+  // viz::CompositorFrameSinkSupportClient implementation.
   void DidReceiveCompositorFrameAck(
       const std::vector<cc::ReturnedResource>& resources) override;
   void OnBeginFrame(const cc::BeginFrameArgs& args) override;
@@ -146,7 +146,7 @@
   bool fallback_tick_pending_ = false;
   bool fallback_tick_running_ = false;
 
-  class StubDisplayClient : public cc::DisplayClient {
+  class StubDisplayClient : public viz::DisplayClient {
     void DisplayOutputSurfaceLost() override {}
     void DisplayWillDrawAndSwap(
         bool will_draw_and_swap,
@@ -164,12 +164,12 @@
   gfx::Size display_size_;
   float device_scale_factor_ = 0;
   // Uses frame_sink_manager_.
-  std::unique_ptr<cc::CompositorFrameSinkSupport> root_support_;
+  std::unique_ptr<viz::CompositorFrameSinkSupport> root_support_;
   // Uses frame_sink_manager_.
-  std::unique_ptr<cc::CompositorFrameSinkSupport> child_support_;
+  std::unique_ptr<viz::CompositorFrameSinkSupport> child_support_;
   StubDisplayClient display_client_;
   // Uses frame_sink_manager_.
-  std::unique_ptr<cc::Display> display_;
+  std::unique_ptr<viz::Display> display_;
   // Owned by |display_|.
   SoftwareOutputSurface* software_output_surface_ = nullptr;
   std::unique_ptr<cc::BeginFrameSource> begin_frame_source_;
diff --git a/content/renderer/dom_storage/local_storage_cached_area_unittest.cc b/content/renderer/dom_storage/local_storage_cached_area_unittest.cc
index 9050e9b5..d9676ceb 100644
--- a/content/renderer/dom_storage/local_storage_cached_area_unittest.cc
+++ b/content/renderer/dom_storage/local_storage_cached_area_unittest.cc
@@ -108,6 +108,8 @@
 
   void Flush() { bindings_.FlushForTesting(); }
 
+  void CloseAllBindings() { bindings_.CloseAllBindings(); }
+
   using ResultCallback = base::OnceCallback<void(bool)>;
   std::list<ResultCallback> pending_callbacks_;
   bool observed_get_all_ = false;
@@ -402,4 +404,37 @@
             non_ascii_key.size() * 2);
 }
 
+TEST_F(LocalStorageCachedAreaTest, BrowserDisconnect) {
+  scoped_refptr<LocalStorageCachedArea> cached_area =
+      cached_areas_.GetCachedArea(kOrigin);
+
+  // GetLength to prime the cache.
+  mock_leveldb_wrapper_.get_all_return_values_[String16ToUint8Vector(kKey)] =
+      String16ToUint8Vector(kValue);
+  EXPECT_EQ(1u, cached_area->GetLength());
+  EXPECT_TRUE(IsCacheLoaded(cached_area.get()));
+  mock_leveldb_wrapper_.CompleteAllPendingCallbacks();
+  mock_leveldb_wrapper_.ResetObservations();
+
+  // Now disconnect the pipe from the browser, simulating situations where the
+  // browser might be forced to destroy the LevelDBWrapperImpl.
+  mock_leveldb_wrapper_.CloseAllBindings();
+
+  // Getters should still function.
+  EXPECT_EQ(1u, cached_area->GetLength());
+  EXPECT_EQ(kValue, cached_area->GetItem(kKey).string());
+
+  // And setters should also still function.
+  cached_area->RemoveItem(kKey, kPageUrl, kStorageAreaId);
+  EXPECT_EQ(0u, cached_area->GetLength());
+  EXPECT_TRUE(cached_area->GetItem(kKey).is_null());
+
+  // Even resetting the cache should still allow class to function properly.
+  ResetCacheOnly(cached_area.get());
+  EXPECT_TRUE(cached_area->GetItem(kKey).is_null());
+  EXPECT_TRUE(cached_area->SetItem(kKey, kValue, kPageUrl, kStorageAreaId));
+  EXPECT_EQ(1u, cached_area->GetLength());
+  EXPECT_EQ(kValue, cached_area->GetItem(kKey).string());
+}
+
 }  // namespace content
diff --git a/content/renderer/renderer_v2.sb b/content/renderer/renderer_v2.sb
index c760822..28e00ba 100644
--- a/content/renderer/renderer_v2.sb
+++ b/content/renderer/renderer_v2.sb
@@ -127,8 +127,9 @@
   (global-name "com.apple.system.opendirectoryd.libinfo")
   (global-name "com.apple.windowserver.active"))
 
-; MacOS dropped FontServer to replace it with the (XPC based) com.apple.fonts.
-(if (< os-version 1010)
+; MacOS dropped FontServer to replace it with the (XPC based) com.apple.fonts,
+; but 10.9 through 10.11 use FontServer.
+(if (< os-version 1012)
   (allow mach-lookup (global-name "com.apple.FontServer")))
 
 ; sysctl
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 0e70354..2ef46a4a 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -250,9 +250,6 @@
     "//cc/ipc:interfaces",
     "//cc/surfaces",
     "//components/leveldb/public/interfaces",
-    "//components/viz/common",
-    "//components/viz/host",
-    "//components/viz/service",
     "//content/app:both_for_content_tests",
     "//content/browser:for_content_tests",
     "//content/browser/speech/proto",
@@ -370,6 +367,9 @@
 
   if (use_aura || is_mac) {
     deps += [
+      "//components/viz/common",
+      "//components/viz/host",
+      "//components/viz/service",
       "//third_party/libvpx",
       "//ui/compositor",
     ]
@@ -508,7 +508,7 @@
   deps = [
     ":test_support",
     "//cc",
-    "//cc/blink",
+    "//components/viz/test:test_support",
     "//content/browser:for_content_tests",
     "//content/child:for_content_tests",
     "//content/public/common",
diff --git a/content/test/DEPS b/content/test/DEPS
index 873b1d4..5cb5756 100644
--- a/content/test/DEPS
+++ b/content/test/DEPS
@@ -24,6 +24,7 @@
 
 specific_include_rules = {
   "layouttest_support.cc": [
+    "+components/viz/test",
     "+content/shell/test_runner",
     "+content/shell/common/shell_switches.h",
     "+services/ui/public/cpp/gpu",
diff --git a/content/test/data/media/webui/integration_test.html b/content/test/data/media/webui/integration_test.html
index 63aee243..58e199f 100644
--- a/content/test/data/media/webui/integration_test.html
+++ b/content/test/data/media/webui/integration_test.html
@@ -50,14 +50,6 @@
         assertEquals(event.params.fps, info.properties.fps);
       };
 
-      // Remove a player.
-      window.testOnRenderTerminated = function() {
-        window.testOnMediaEvent();
-
-        window.media.onRendererTerminated(TEST_RENDERER);
-        assertEquals(undefined, window.manager.players_[TEST_NAME]);
-      };
-
       window.testAudioComponents = function() {
         var event = {
           component_id: 1,
diff --git a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
index d9720f8c..eb6e7e0 100644
--- a/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
+++ b/content/test/gpu/gpu_tests/webgl_conformance_expectations.py
@@ -610,6 +610,41 @@
         ['android', 'android-chromium',
          ('nvidia', 'NVIDIA Tegra')], bug=624621)
 
+    # Nexus 9 and Shield TV (NVIDIA GPUs currently on the waterfall)
+    self.Fail('conformance/ogles/GL/array/array_001_to_006.html',
+              ['android', 'nvidia'], bug=740769)
+    self.Fail('conformance/ogles/GL/functions/functions_009_to_016.html',
+              ['android', 'nvidia'], bug=740769)
+    self.Fail('conformance/ogles/GL/functions/functions_017_to_024.html',
+              ['android', 'nvidia'], bug=740769)
+    self.Fail('conformance/ogles/GL/functions/functions_025_to_032.html',
+              ['android', 'nvidia'], bug=740769)
+    self.Fail('conformance/ogles/GL/functions/functions_033_to_040.html',
+              ['android', 'nvidia'], bug=740769)
+    self.Fail('conformance/ogles/GL/functions/functions_041_to_048.html',
+              ['android', 'nvidia'], bug=740769)
+    self.Fail('conformance/ogles/GL/functions/functions_049_to_056.html',
+              ['android', 'nvidia'], bug=740769)
+    self.Fail('conformance/ogles/GL/functions/functions_057_to_064.html',
+              ['android', 'nvidia'], bug=740769)
+    self.Fail('conformance/ogles/GL/functions/functions_065_to_072.html',
+              ['android', 'nvidia'], bug=740769)
+    self.Fail('conformance/ogles/GL/functions/functions_073_to_080.html',
+              ['android', 'nvidia'], bug=740769)
+    self.Fail('conformance/ogles/GL/functions/functions_081_to_088.html',
+              ['android', 'nvidia'], bug=740769)
+    self.Fail('conformance/ogles/GL/functions/functions_089_to_096.html',
+              ['android', 'nvidia'], bug=740769)
+    self.Fail('conformance/ogles/GL/functions/functions_097_to_104.html',
+              ['android', 'nvidia'], bug=740769)
+    self.Fail('conformance/ogles/GL/functions/functions_105_to_112.html',
+              ['android', 'nvidia'], bug=740769)
+    self.Fail('conformance/ogles/GL/functions/functions_113_to_120.html',
+              ['android', 'nvidia'], bug=740769)
+    self.Fail('conformance/ogles/GL/functions/functions_121_to_126.html',
+              ['android', 'nvidia'], bug=740769)
+
+
     ############
     # ChromeOS #
     ############
diff --git a/content/test/layouttest_support.cc b/content/test/layouttest_support.cc
index 427ab50..cf5b1b2 100644
--- a/content/test/layouttest_support.cc
+++ b/content/test/layouttest_support.cc
@@ -19,7 +19,7 @@
 #include "cc/base/switches.h"
 #include "cc/output/copy_output_request.h"
 #include "cc/test/pixel_test_output_surface.h"
-#include "cc/test/test_layer_tree_frame_sink.h"
+#include "components/viz/test/test_layer_tree_frame_sink.h"
 #include "content/browser/bluetooth/bluetooth_device_chooser_controller.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/renderer_host/render_widget_host_impl.h"
@@ -293,7 +293,7 @@
 class CopyRequestSwapPromise : public cc::SwapPromise {
  public:
   using FindLayerTreeFrameSinkCallback =
-      base::Callback<cc::TestLayerTreeFrameSink*()>;
+      base::Callback<viz::TestLayerTreeFrameSink*()>;
   CopyRequestSwapPromise(
       std::unique_ptr<cc::CopyOutputRequest> request,
       FindLayerTreeFrameSinkCallback find_layer_tree_frame_sink_callback)
@@ -323,13 +323,13 @@
  private:
   std::unique_ptr<cc::CopyOutputRequest> copy_request_;
   FindLayerTreeFrameSinkCallback find_layer_tree_frame_sink_callback_;
-  cc::TestLayerTreeFrameSink* layer_tree_frame_sink_from_commit_ = nullptr;
+  viz::TestLayerTreeFrameSink* layer_tree_frame_sink_from_commit_ = nullptr;
 };
 
 }  // namespace
 
 class LayoutTestDependenciesImpl : public LayoutTestDependencies,
-                                   public cc::TestLayerTreeFrameSinkClient {
+                                   public viz::TestLayerTreeFrameSinkClient {
  public:
   std::unique_ptr<cc::LayerTreeFrameSink> CreateLayerTreeFrameSink(
       int32_t routing_id,
@@ -358,7 +358,7 @@
 
     constexpr bool disable_display_vsync = false;
     constexpr double refresh_rate = 60.0;
-    auto layer_tree_frame_sink = base::MakeUnique<cc::TestLayerTreeFrameSink>(
+    auto layer_tree_frame_sink = base::MakeUnique<viz::TestLayerTreeFrameSink>(
         std::move(compositor_context_provider),
         std::move(worker_context_provider), nullptr /* shared_bitmap_manager */,
         gpu_memory_buffer_manager, renderer_settings, task_runner,
@@ -425,7 +425,7 @@
   void DisplayDidDrawAndSwap() override {}
 
  private:
-  cc::TestLayerTreeFrameSink* FindLayerTreeFrameSink(int32_t routing_id) {
+  viz::TestLayerTreeFrameSink* FindLayerTreeFrameSink(int32_t routing_id) {
     auto it = layer_tree_frame_sinks_.find(routing_id);
     return it == layer_tree_frame_sinks_.end() ? nullptr : it->second;
   }
@@ -434,7 +434,7 @@
   // layout tests, so this memory usage does not occur in production.
   // Entries in this map will outlive the output surface, because this object is
   // owned by RenderThreadImpl, which outlives layout test execution.
-  std::unordered_map<int32_t, cc::TestLayerTreeFrameSink*>
+  std::unordered_map<int32_t, viz::TestLayerTreeFrameSink*>
       layer_tree_frame_sinks_;
   scoped_refptr<gpu::GpuChannelHost> gpu_channel_;
 };
diff --git a/device/geolocation/BUILD.gn b/device/geolocation/BUILD.gn
index c4fa807..27069c5 100644
--- a/device/geolocation/BUILD.gn
+++ b/device/geolocation/BUILD.gn
@@ -18,6 +18,8 @@
     "android/geolocation_jni_registrar.h",
     "empty_wifi_data_provider.cc",
     "empty_wifi_data_provider.h",
+    "geolocation_config.cc",
+    "geolocation_config.h",
     "geolocation_context.cc",
     "geolocation_context.h",
     "geolocation_delegate.cc",
diff --git a/device/geolocation/geolocation_config.cc b/device/geolocation/geolocation_config.cc
new file mode 100644
index 0000000..7ab8a8d
--- /dev/null
+++ b/device/geolocation/geolocation_config.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 "device/geolocation/geolocation_config.h"
+
+#include "base/bind.h"
+#include "mojo/public/cpp/bindings/strong_binding.h"
+
+namespace device {
+
+GeolocationConfig::GeolocationConfig() {}
+
+GeolocationConfig::~GeolocationConfig() {}
+
+// static
+void GeolocationConfig::Create(
+    const service_manager::BindSourceInfo& source_info,
+    mojom::GeolocationConfigRequest request) {
+  mojo::MakeStrongBinding(base::MakeUnique<GeolocationConfig>(),
+                          std::move(request));
+}
+
+void GeolocationConfig::IsHighAccuracyLocationBeingCaptured(
+    IsHighAccuracyLocationBeingCapturedCallback callback) {
+  std::move(callback).Run(
+      GeolocationProvider::GetInstance()->HighAccuracyLocationInUse());
+}
+
+}  // namespace device
diff --git a/device/geolocation/geolocation_config.h b/device/geolocation/geolocation_config.h
new file mode 100644
index 0000000..9aafb4d
--- /dev/null
+++ b/device/geolocation/geolocation_config.h
@@ -0,0 +1,39 @@
+// 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 DEVICE_GEOLOCATION_GEOLOCATION_CONFIG_H_
+#define DEVICE_GEOLOCATION_GEOLOCATION_CONFIG_H_
+
+#include "base/compiler_specific.h"
+#include "device/geolocation/geolocation_export.h"
+#include "device/geolocation/geolocation_provider_impl.h"
+#include "device/geolocation/public/interfaces/geolocation_config.mojom.h"
+#include "mojo/public/cpp/bindings/binding.h"
+
+namespace service_manager {
+struct BindSourceInfo;
+}
+
+namespace device {
+
+// Implements the GeolocationConfig Mojo interface.
+class DEVICE_GEOLOCATION_EXPORT GeolocationConfig
+    : public NON_EXPORTED_BASE(mojom::GeolocationConfig) {
+ public:
+  GeolocationConfig();
+  ~GeolocationConfig() override;
+
+  static void Create(const service_manager::BindSourceInfo& source_info,
+                     mojom::GeolocationConfigRequest request);
+
+  void IsHighAccuracyLocationBeingCaptured(
+      IsHighAccuracyLocationBeingCapturedCallback callback) override;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(GeolocationConfig);
+};
+
+}  // namespace device
+
+#endif  // DEVICE_GEOLOCATION_GEOLOCATION_CONFIG_H_
diff --git a/device/geolocation/geolocation_provider.h b/device/geolocation/geolocation_provider.h
index 272b6fb2..07f58fe4 100644
--- a/device/geolocation/geolocation_provider.h
+++ b/device/geolocation/geolocation_provider.h
@@ -50,6 +50,8 @@
   // go/chrome-privacy-doc.
   virtual void UserDidOptIntoLocationServices() = 0;
 
+  virtual bool HighAccuracyLocationInUse() = 0;
+
   // Overrides the current location for testing.
   //
   // Overrides the location for automation/testing. Suppresses any further
diff --git a/device/geolocation/geolocation_provider_impl.cc b/device/geolocation/geolocation_provider_impl.cc
index 55cbc77..9cba7692 100644
--- a/device/geolocation/geolocation_provider_impl.cc
+++ b/device/geolocation/geolocation_provider_impl.cc
@@ -67,6 +67,10 @@
     InformProvidersPermissionGranted();
 }
 
+bool GeolocationProviderImpl::HighAccuracyLocationInUse() {
+  return !high_accuracy_callbacks_.empty();
+}
+
 void GeolocationProviderImpl::OverrideLocationForTesting(
     const Geoposition& position) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
diff --git a/device/geolocation/geolocation_provider_impl.h b/device/geolocation/geolocation_provider_impl.h
index b08f3af..4f9c4da 100644
--- a/device/geolocation/geolocation_provider_impl.h
+++ b/device/geolocation/geolocation_provider_impl.h
@@ -35,6 +35,7 @@
       const LocationUpdateCallback& callback,
       bool enable_high_accuracy) override;
   void UserDidOptIntoLocationServices() override;
+  bool HighAccuracyLocationInUse() override;
   void OverrideLocationForTesting(const Geoposition& position) override;
 
   // Callback from the LocationArbitrator. Public for testing.
diff --git a/device/geolocation/public/interfaces/BUILD.gn b/device/geolocation/public/interfaces/BUILD.gn
index 44b518f..3d03e66 100644
--- a/device/geolocation/public/interfaces/BUILD.gn
+++ b/device/geolocation/public/interfaces/BUILD.gn
@@ -7,6 +7,7 @@
 mojom("interfaces") {
   sources = [
     "geolocation.mojom",
+    "geolocation_config.mojom",
     "geoposition.mojom",
   ]
 }
diff --git a/device/geolocation/public/interfaces/geolocation_config.mojom b/device/geolocation/public/interfaces/geolocation_config.mojom
new file mode 100644
index 0000000..0bf5dd7
--- /dev/null
+++ b/device/geolocation/public/interfaces/geolocation_config.mojom
@@ -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.
+
+module device.mojom;
+
+// Provides an interface for browser process to access geolocation capturing
+// config.
+interface GeolocationConfig {
+  // Returns true if the location is being captured and high_accuracy is
+  // enabled.
+  IsHighAccuracyLocationBeingCaptured() => (bool high_accuracy);
+};
diff --git a/docs/ios/build_instructions.md b/docs/ios/build_instructions.md
index f24adbf..570a106 100644
--- a/docs/ios/build_instructions.md
+++ b/docs/ios/build_instructions.md
@@ -14,14 +14,6 @@
 
 * A 64-bit Mac running 10.11+.
 * [Xcode](https://developer.apple.com/xcode) 8.0+.
-* The OS X 10.10 SDK. Run
-
-    ```shell
-    $ ls `xcode-select -p`/Platforms/MacOSX.platform/Developer/SDKs
-    ```
-
-  to check whether you have it.  Building with the 10.11 SDK works too, but
-  the releases currently use the 10.10 SDK.
 * The current version of the JDK (required for the Closure compiler).
 
 ## Install `depot_tools`
diff --git a/docs/testing/web_platform_tests.md b/docs/testing/web_platform_tests.md
index d3bc522..acdf2cc 100644
--- a/docs/testing/web_platform_tests.md
+++ b/docs/testing/web_platform_tests.md
@@ -42,7 +42,7 @@
 -   Recent logs on Buildbot for [wpt-importer
     builder](https://build.chromium.org/p/chromium.infra.cron/builders/wpt-importer)
 -   Recent CLs created by
-    [blink-w3c-test-autoroller@chromium.org](https://codereview.chromium.org/search?owner=blink-w3c-test-autoroller%40chromium.org).
+    [blink-w3c-test-autoroller@chromium.org](https://chromium-review.googlesource.com/q/owner:blink-w3c-test-autoroller%40chromium.org).
 
 Automatic imports are intended to run at least once every 24 hours.
 
diff --git a/docs/updating_clang.md b/docs/updating_clang.md
index a08566dd..116c5b27 100644
--- a/docs/updating_clang.md
+++ b/docs/updating_clang.md
@@ -29,7 +29,8 @@
     git cl try &&
     git cl try -m tryserver.chromium.mac -b mac_chromium_asan_rel_ng &&
     git cl try -m tryserver.chromium.linux -b linux_chromium_chromeos_dbg_ng \
-      -b linux_chromium_chromeos_asan_rel_ng -b linux_chromium_msan_rel_ng &&
+      -b linux_chromium_chromeos_asan_rel_ng -b linux_chromium_msan_rel_ng \
+      -b fuchsia &&
     git cl try -m tryserver.blink -b linux_trusty_blink_rel
 ```
 1.  Commit roll CL from the first step
diff --git a/extensions/browser/api/messaging/native_message_host.cc b/extensions/browser/api/messaging/native_message_host.cc
index f3bb082f..7216051e 100644
--- a/extensions/browser/api/messaging/native_message_host.cc
+++ b/extensions/browser/api/messaging/native_message_host.cc
@@ -15,7 +15,7 @@
     "Specified native messaging host not found.";
 const char NativeMessageHost::kForbiddenError[] =
     "Access to the specified native messaging host is forbidden.";
-const char NativeMessageHost::kHostInputOuputError[] =
+const char NativeMessageHost::kHostInputOutputError[] =
     "Error when communicating with the native messaging host.";
 
 }  // extensions
diff --git a/extensions/browser/api/messaging/native_message_host.h b/extensions/browser/api/messaging/native_message_host.h
index 2d4b82f..094083e 100644
--- a/extensions/browser/api/messaging/native_message_host.h
+++ b/extensions/browser/api/messaging/native_message_host.h
@@ -24,7 +24,7 @@
   static const char kNativeHostExited[];
   static const char kNotFoundError[];
   static const char kForbiddenError[];
-  static const char kHostInputOuputError[];
+  static const char kHostInputOutputError[];
 
   // Callback interface for receiving messages from the native host.
   class Client {
diff --git a/extensions/shell/installer/linux/BUILD.gn b/extensions/shell/installer/linux/BUILD.gn
index 555d85a..08f8bfa 100644
--- a/extensions/shell/installer/linux/BUILD.gn
+++ b/extensions/shell/installer/linux/BUILD.gn
@@ -132,7 +132,7 @@
   # TODO(thomasanderson): Move this variable into a .gni file
   # somewhere.  It is currently copied from
   # buildtools/third_party/libc++/BUILD.gn.
-  libcpp_is_static = !is_component_build && !is_asan && !is_msan && !is_tsan
+  libcpp_is_static = !is_component_build && !using_sanitizer
   if (!libcpp_is_static && use_custom_libcxx) {
     public_deps += [ "//buildtools/third_party/libc++:libc++" ]
   }
@@ -165,7 +165,7 @@
   # TODO(thomasanderson): Move this variable into a .gni file
   # somewhere.  It is currently copied from
   # buildtools/third_party/libc++/BUILD.gn.
-  libcpp_is_static = !is_component_build && !is_asan && !is_msan && !is_tsan
+  libcpp_is_static = !is_component_build && !using_sanitizer
   if (!libcpp_is_static && use_custom_libcxx) {
     packaging_files_binaries += [ "$root_out_dir/libc++.so" ]
   }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 4a8a74d..6f68692 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -86,6 +86,7 @@
 #include "ui/gl/gl_implementation.h"
 #include "ui/gl/gl_surface.h"
 #include "ui/gl/gl_version_info.h"
+#include "ui/gl/gl_workarounds.h"
 #include "ui/gl/gpu_timing.h"
 
 #if defined(OS_MACOSX)
@@ -3186,6 +3187,13 @@
   // Create GPU Tracer for timing values.
   gpu_tracer_.reset(new GPUTracer(this));
 
+  // Pass some workarounds to GLContext so that we can apply them in RealGLApi.
+  gl::GLWorkarounds gl_workarounds;
+  if (workarounds().clear_to_zero_or_one_broken) {
+    gl_workarounds.clear_to_zero_or_one_broken = true;
+  }
+  GetGLContext()->SetGLWorkarounds(gl_workarounds);
+
   if (workarounds().disable_timestamp_queries) {
     // Forcing time elapsed query for any GPU Timing Client forces it for all
     // clients in the context.
@@ -4337,8 +4345,6 @@
 
 void GLES2DecoderImpl::ProcessFinishedAsyncTransfers() {
   ProcessPendingReadPixels(false);
-  if (query_manager_.get())
-    query_manager_->ProcessPendingTransferQueries();
 }
 
 static void RebindCurrentFramebuffer(
@@ -16158,8 +16164,7 @@
 void GLES2DecoderImpl::ProcessPendingQueries(bool did_finish) {
   if (!query_manager_.get())
     return;
-  if (!query_manager_->ProcessPendingQueries(did_finish))
-    current_decoder_error_ = error::kOutOfBounds;
+  query_manager_->ProcessPendingQueries(did_finish);
 }
 
 // Note that if there are no pending readpixels right now,
@@ -16293,6 +16298,14 @@
     return error::kNoError;
   }
 
+  scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_shm_id);
+  if (!buffer)
+    return error::kInvalidArguments;
+  QuerySync* sync = static_cast<QuerySync*>(
+      buffer->GetDataAddress(sync_shm_offset, sizeof(QuerySync)));
+  if (!sync)
+    return error::kOutOfBounds;
+
   QueryManager::Query* query = query_manager_->GetQuery(client_id);
   if (!query) {
     if (!query_manager_->IsValidQuery(client_id)) {
@@ -16301,24 +16314,21 @@
                          "id not made by glGenQueriesEXT");
       return error::kNoError;
     }
-    query = query_manager_->CreateQuery(
-        target, client_id, sync_shm_id, sync_shm_offset);
+
+    query =
+        query_manager_->CreateQuery(target, client_id, std::move(buffer), sync);
+  } else {
+    if (query->target() != target) {
+      LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glBeginQueryEXT",
+                         "target does not match");
+      return error::kNoError;
+    } else if (query->sync() != sync) {
+      DLOG(ERROR) << "Shared memory used by query not the same as before";
+      return error::kInvalidArguments;
+    }
   }
 
-  if (query->target() != target) {
-    LOCAL_SET_GL_ERROR(
-        GL_INVALID_OPERATION, "glBeginQueryEXT", "target does not match");
-    return error::kNoError;
-  } else if (query->shm_id() != sync_shm_id ||
-             query->shm_offset() != sync_shm_offset) {
-    DLOG(ERROR) << "Shared memory used by query not the same as before";
-    return error::kInvalidArguments;
-  }
-
-  if (!query_manager_->BeginQuery(query)) {
-    return error::kOutOfBounds;
-  }
-
+  query_manager_->BeginQuery(query);
   return error::kNoError;
 }
 
@@ -16337,12 +16347,7 @@
     return error::kNoError;
   }
 
-  if (!query_manager_->EndQuery(query, submit_count)) {
-    return error::kOutOfBounds;
-  }
-
-  query_manager_->ProcessPendingTransferQueries();
-
+  query_manager_->EndQuery(query, submit_count);
   return error::kNoError;
 }
 
@@ -16373,6 +16378,14 @@
       return error::kNoError;
   }
 
+  scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_shm_id);
+  if (!buffer)
+    return error::kInvalidArguments;
+  QuerySync* sync = static_cast<QuerySync*>(
+      buffer->GetDataAddress(sync_shm_offset, sizeof(QuerySync)));
+  if (!sync)
+    return error::kOutOfBounds;
+
   QueryManager::Query* query = query_manager_->GetQuery(client_id);
   if (!query) {
     if (!query_manager_->IsValidQuery(client_id)) {
@@ -16381,12 +16394,10 @@
                          "id not made by glGenQueriesEXT");
       return error::kNoError;
     }
-    query = query_manager_->CreateQuery(
-        target, client_id, sync_shm_id, sync_shm_offset);
+    query =
+        query_manager_->CreateQuery(target, client_id, std::move(buffer), sync);
   }
-  if (!query_manager_->QueryCounter(query, submit_count)) {
-    return error::kOutOfBounds;
-  }
+  query_manager_->QueryCounter(query, submit_count);
 
   return error::kNoError;
 }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
index dcb3caaa..fa07187 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.cc
@@ -72,6 +72,29 @@
   texture_object_map.clear();
 }
 
+GLES2DecoderPassthroughImpl::PendingQuery::PendingQuery() = default;
+GLES2DecoderPassthroughImpl::PendingQuery::~PendingQuery() = default;
+GLES2DecoderPassthroughImpl::PendingQuery::PendingQuery(const PendingQuery&) =
+    default;
+GLES2DecoderPassthroughImpl::PendingQuery::PendingQuery(PendingQuery&&) =
+    default;
+GLES2DecoderPassthroughImpl::PendingQuery&
+GLES2DecoderPassthroughImpl::PendingQuery::operator=(const PendingQuery&) =
+    default;
+GLES2DecoderPassthroughImpl::PendingQuery&
+GLES2DecoderPassthroughImpl::PendingQuery::operator=(PendingQuery&&) = default;
+
+GLES2DecoderPassthroughImpl::ActiveQuery::ActiveQuery() = default;
+GLES2DecoderPassthroughImpl::ActiveQuery::~ActiveQuery() = default;
+GLES2DecoderPassthroughImpl::ActiveQuery::ActiveQuery(const ActiveQuery&) =
+    default;
+GLES2DecoderPassthroughImpl::ActiveQuery::ActiveQuery(ActiveQuery&&) = default;
+GLES2DecoderPassthroughImpl::ActiveQuery&
+GLES2DecoderPassthroughImpl::ActiveQuery::operator=(const ActiveQuery&) =
+    default;
+GLES2DecoderPassthroughImpl::ActiveQuery&
+GLES2DecoderPassthroughImpl::ActiveQuery::operator=(ActiveQuery&&) = default;
+
 GLES2DecoderPassthroughImpl::GLES2DecoderPassthroughImpl(
     GLES2DecoderClient* client,
     CommandBufferServiceBase* command_buffer_service,
@@ -950,16 +973,9 @@
       break;
     }
 
-    QuerySync* sync = GetSharedMemoryAs<QuerySync*>(
-        query.shm_id, query.shm_offset, sizeof(QuerySync));
-    if (sync == nullptr) {
-      pending_queries_.pop_front();
-      return error::kOutOfBounds;
-    }
-
     // Mark the query as complete
-    sync->result = result;
-    base::subtle::Release_Store(&sync->process_count, query.submit_count);
+    query.sync->result = result;
+    base::subtle::Release_Store(&query.sync->process_count, query.submit_count);
     pending_queries_.pop_front();
   }
 
@@ -975,13 +991,10 @@
                      return pending_query.service_id == service_id;
                    });
   if (pending_iter != pending_queries_.end()) {
-    QuerySync* sync = GetSharedMemoryAs<QuerySync*>(
-        pending_iter->shm_id, pending_iter->shm_offset, sizeof(QuerySync));
-    if (sync != nullptr) {
-      sync->result = 0;
-      base::subtle::Release_Store(&sync->process_count,
-                                  pending_iter->submit_count);
-    }
+    QuerySync* sync = pending_iter->sync;
+    sync->result = 0;
+    base::subtle::Release_Store(&sync->process_count,
+                                pending_iter->submit_count);
 
     pending_queries_.erase(pending_iter);
   }
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
index 420dd28..90048c4 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough.h
@@ -374,20 +374,34 @@
 
   // All queries that are waiting for their results to be ready
   struct PendingQuery {
+    PendingQuery();
+    ~PendingQuery();
+    PendingQuery(const PendingQuery&);
+    PendingQuery(PendingQuery&&);
+    PendingQuery& operator=(const PendingQuery&);
+    PendingQuery& operator=(PendingQuery&&);
+
     GLenum target = GL_NONE;
     GLuint service_id = 0;
 
-    int32_t shm_id = 0;
-    uint32_t shm_offset = 0;
+    scoped_refptr<gpu::Buffer> shm;
+    QuerySync* sync = nullptr;
     base::subtle::Atomic32 submit_count = 0;
   };
   std::deque<PendingQuery> pending_queries_;
 
   // Currently active queries
   struct ActiveQuery {
+    ActiveQuery();
+    ~ActiveQuery();
+    ActiveQuery(const ActiveQuery&);
+    ActiveQuery(ActiveQuery&&);
+    ActiveQuery& operator=(const ActiveQuery&);
+    ActiveQuery& operator=(ActiveQuery&&);
+
     GLuint service_id = 0;
-    int32_t shm_id = 0;
-    uint32_t shm_offset = 0;
+    scoped_refptr<gpu::Buffer> shm;
+    QuerySync* sync = nullptr;
   };
   std::unordered_map<GLenum, ActiveQuery> active_queries_;
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
index 6a1cbc9..030c3be5 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -2602,6 +2602,14 @@
     return error::kUnknownCommand;
   }
 
+  scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_shm_id);
+  if (!buffer)
+    return error::kInvalidArguments;
+  QuerySync* sync = static_cast<QuerySync*>(
+      buffer->GetDataAddress(sync_shm_offset, sizeof(QuerySync)));
+  if (!sync)
+    return error::kOutOfBounds;
+
   GLuint service_id = GetQueryServiceID(id, &query_id_map_);
 
   // Flush all previous errors
@@ -2624,8 +2632,8 @@
   PendingQuery pending_query;
   pending_query.target = target;
   pending_query.service_id = service_id;
-  pending_query.shm_id = sync_shm_id;
-  pending_query.shm_offset = sync_shm_offset;
+  pending_query.shm = std::move(buffer);
+  pending_query.sync = sync;
   pending_query.submit_count = submit_count;
   pending_queries_.push_back(pending_query);
 
@@ -2640,6 +2648,14 @@
   GLuint service_id = GetQueryServiceID(id, &query_id_map_);
   QueryInfo* query_info = &query_info_map_[service_id];
 
+  scoped_refptr<gpu::Buffer> buffer = GetSharedMemoryBuffer(sync_shm_id);
+  if (!buffer)
+    return error::kInvalidArguments;
+  QuerySync* sync = static_cast<QuerySync*>(
+      buffer->GetDataAddress(sync_shm_offset, sizeof(QuerySync)));
+  if (!sync)
+    return error::kOutOfBounds;
+
   if (IsEmulatedQueryTarget(target)) {
     if (active_queries_.find(target) != active_queries_.end()) {
       InsertError(GL_INVALID_OPERATION, "Query already active on target.");
@@ -2676,8 +2692,8 @@
 
   ActiveQuery query;
   query.service_id = service_id;
-  query.shm_id = sync_shm_id;
-  query.shm_offset = sync_shm_offset;
+  query.shm = std::move(buffer);
+  query.sync = sync;
   active_queries_[target] = query;
 
   return error::kNoError;
@@ -2709,14 +2725,14 @@
   }
 
   DCHECK(active_queries_.find(target) != active_queries_.end());
-  ActiveQuery active_query = active_queries_[target];
+  ActiveQuery active_query = std::move(active_queries_[target]);
   active_queries_.erase(target);
 
   PendingQuery pending_query;
   pending_query.target = target;
   pending_query.service_id = active_query.service_id;
-  pending_query.shm_id = active_query.shm_id;
-  pending_query.shm_offset = active_query.shm_offset;
+  pending_query.shm = std::move(active_query.shm);
+  pending_query.sync = active_query.sync;
   pending_query.submit_count = submit_count;
   pending_queries_.push_back(pending_query);
 
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
index 45811dc..e23813a3 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest.cc
@@ -639,7 +639,7 @@
   return test->ExecuteCmd(query_counter_cmd);
 }
 
-static bool ProcessQuery(GLES2DecoderTestBase* test,
+static void ProcessQuery(GLES2DecoderTestBase* test,
                          ::gl::MockGLInterface* gl,
                          GLenum target,
                          GLuint service_id) {
@@ -659,16 +659,12 @@
   }
 
   QueryManager* query_manager = test->GetDecoder()->GetQueryManager();
-  EXPECT_TRUE(nullptr != query_manager);
-  if (!query_manager)
-    return false;
-
-  return query_manager->ProcessPendingQueries(false);
+  ASSERT_TRUE(nullptr != query_manager);
+  query_manager->ProcessPendingQueries(false);
 }
 
 static void CheckBeginEndQueryBadMemoryFails(GLES2DecoderTestBase* test,
                                              GLuint client_id,
-                                             GLuint service_id,
                                              const QueryType& query_type,
                                              int32_t shm_id,
                                              uint32_t shm_offset) {
@@ -683,43 +679,29 @@
   init.request_alpha = true;
   init.bind_generates_resource = true;
   test->InitDecoder(init);
-  ::testing::StrictMock<::gl::MockGLInterface>* gl = test->GetGLMock();
-  ::gl::GPUTimingFake gpu_timing_queries;
 
-  ExecuteGenerateQueryCmd(test, gl, query_type.type,
-                          client_id, service_id);
+  test->GenHelper<GenQueriesEXTImmediate>(client_id);
 
   // Test bad shared memory fails
-  error::Error error1 = error::kNoError;
-  error::Error error2 = error::kNoError;
+  error::Error error = error::kNoError;
   if (query_type.is_counter) {
-    error1 =
-        ExecuteQueryCounterCmd(test, gl, &gpu_timing_queries, query_type.type,
-                               client_id, service_id, shm_id, shm_offset, 1);
+    QueryCounterEXT query_counter_cmd;
+    query_counter_cmd.Init(client_id, query_type.type, shm_id, shm_offset, 1);
+    error = test->ExecuteCmd(query_counter_cmd);
   } else {
-    error1 = ExecuteBeginQueryCmd(test, gl, &gpu_timing_queries,
-                                  query_type.type,
-                                  client_id, service_id,
-                                  shm_id, shm_offset);
-    error2 = ExecuteEndQueryCmd(test, gl, query_type.type, 1);
+    BeginQueryEXT begin_cmd;
+    begin_cmd.Init(query_type.type, client_id, shm_id, shm_offset);
+    error = test->ExecuteCmd(begin_cmd);
   }
 
-  bool process_success = ProcessQuery(test, gl, query_type.type, service_id);
+  EXPECT_TRUE(error != error::kNoError);
 
-  EXPECT_TRUE(error1 != error::kNoError || error2 != error::kNoError ||
-              !process_success);
-
-  if (GL_ANY_SAMPLES_PASSED_EXT == query_type.type)
-    EXPECT_CALL(*gl, DeleteQueries(1, _)).Times(1).RetiresOnSaturation();
   test->ResetDecoder();
 }
 
 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryIdFails) {
   for (size_t i = 0; i < arraysize(kQueryTypes); ++i) {
-    CheckBeginEndQueryBadMemoryFails(this,
-                                     kNewClientId,
-                                     kNewServiceId,
-                                     kQueryTypes[i],
+    CheckBeginEndQueryBadMemoryFails(this, kNewClientId, kQueryTypes[i],
                                      kInvalidSharedMemoryId,
                                      kSharedMemoryOffset);
   }
@@ -728,13 +710,12 @@
 TEST_P(GLES2DecoderManualInitTest, BeginEndQueryEXTBadMemoryOffsetFails) {
   for (size_t i = 0; i < arraysize(kQueryTypes); ++i) {
     // Out-of-bounds.
-    CheckBeginEndQueryBadMemoryFails(this, kNewClientId, kNewServiceId,
-                                     kQueryTypes[i], shared_memory_id_,
+    CheckBeginEndQueryBadMemoryFails(this, kNewClientId, kQueryTypes[i],
+                                     shared_memory_id_,
                                      kInvalidSharedMemoryOffset);
     // Overflow.
-    CheckBeginEndQueryBadMemoryFails(this, kNewClientId, kNewServiceId,
-                                     kQueryTypes[i], shared_memory_id_,
-                                     0xfffffffcu);
+    CheckBeginEndQueryBadMemoryFails(this, kNewClientId, kQueryTypes[i],
+                                     shared_memory_id_, 0xfffffffcu);
   }
 }
 
@@ -774,7 +755,7 @@
                                                     query_type.type, 1));
     }
 
-    EXPECT_TRUE(ProcessQuery(this, gl, query_type.type, kNewServiceId));
+    ProcessQuery(this, gl, query_type.type, kNewServiceId);
 
     // Reuse query.
     if (query_type.is_counter) {
@@ -793,7 +774,7 @@
                                                     query_type.type, 2));
     }
 
-    EXPECT_TRUE(ProcessQuery(this, gl, query_type.type, kNewServiceId));
+    ProcessQuery(this, gl, query_type.type, kNewServiceId);
 
     if (GL_ANY_SAMPLES_PASSED_EXT == query_type.type)
       EXPECT_CALL(*gl, DeleteQueries(1, _)).Times(1).RetiresOnSaturation();
@@ -925,9 +906,8 @@
   EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
       .WillOnce(Return(GL_TIMEOUT_EXPIRED))
       .RetiresOnSaturation();
-  bool process_success = query_manager->ProcessPendingQueries(false);
+  query_manager->ProcessPendingQueries(false);
 
-  EXPECT_TRUE(process_success);
   EXPECT_TRUE(query->IsPending());
 
 #if DCHECK_IS_ON()
@@ -938,9 +918,8 @@
   EXPECT_CALL(*gl_, ClientWaitSync(kGlSync, _, _))
       .WillOnce(Return(GL_ALREADY_SIGNALED))
       .RetiresOnSaturation();
-  process_success = query_manager->ProcessPendingQueries(false);
+  query_manager->ProcessPendingQueries(false);
 
-  EXPECT_TRUE(process_success);
   EXPECT_FALSE(query->IsPending());
 
 #if DCHECK_IS_ON()
diff --git a/gpu/command_buffer/service/query_manager.cc b/gpu/command_buffer/service/query_manager.cc
index 56f3594..dd584d0 100644
--- a/gpu/command_buffer/service/query_manager.cc
+++ b/gpu/command_buffer/service/query_manager.cc
@@ -30,11 +30,11 @@
  public:
   AbstractIntegerQuery(QueryManager* manager,
                        GLenum target,
-                       int32_t shm_id,
-                       uint32_t shm_offset);
-  bool Begin() override;
-  bool End(base::subtle::Atomic32 submit_count) override;
-  bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+                       scoped_refptr<gpu::Buffer> buffer,
+                       QuerySync* sync);
+  void Begin() override;
+  void End(base::subtle::Atomic32 submit_count) override;
+  void QueryCounter(base::subtle::Atomic32 submit_count) override;
   void Pause() override;
   void Resume() override;
   void Destroy(bool have_context) override;
@@ -49,16 +49,16 @@
 
 AbstractIntegerQuery::AbstractIntegerQuery(QueryManager* manager,
                                            GLenum target,
-                                           int32_t shm_id,
-                                           uint32_t shm_offset)
-    : Query(manager, target, shm_id, shm_offset) {
+                                           scoped_refptr<gpu::Buffer> buffer,
+                                           QuerySync* sync)
+    : Query(manager, target, std::move(buffer), sync) {
   GLuint service_id = 0;
   glGenQueries(1, &service_id);
   DCHECK_NE(0u, service_id);
   service_ids_.push_back(service_id);
 }
 
-bool AbstractIntegerQuery::Begin() {
+void AbstractIntegerQuery::Begin() {
   MarkAsActive();
   // Delete all but the first one when beginning a new query.
   if (service_ids_.size() > 1) {
@@ -66,17 +66,15 @@
     service_ids_.resize(1);
   }
   BeginQueryHelper(target(), service_ids_.back());
-  return true;
 }
 
-bool AbstractIntegerQuery::End(base::subtle::Atomic32 submit_count) {
+void AbstractIntegerQuery::End(base::subtle::Atomic32 submit_count) {
   EndQueryHelper(target());
-  return AddToPendingQueue(submit_count);
+  AddToPendingQueue(submit_count);
 }
 
-bool AbstractIntegerQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
+void AbstractIntegerQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
   NOTREACHED();
-  return false;
 }
 
 void AbstractIntegerQuery::Pause() {
@@ -116,9 +114,9 @@
  public:
   BooleanQuery(QueryManager* manager,
                GLenum target,
-               int32_t shm_id,
-               uint32_t shm_offset);
-  bool Process(bool did_finish) override;
+               scoped_refptr<gpu::Buffer> buffer,
+               QuerySync* sync);
+  void Process(bool did_finish) override;
 
  protected:
   ~BooleanQuery() override;
@@ -126,35 +124,34 @@
 
 BooleanQuery::BooleanQuery(QueryManager* manager,
                            GLenum target,
-                           int32_t shm_id,
-                           uint32_t shm_offset)
-    : AbstractIntegerQuery(manager, target, shm_id, shm_offset) {}
+                           scoped_refptr<gpu::Buffer> buffer,
+                           QuerySync* sync)
+    : AbstractIntegerQuery(manager, target, std::move(buffer), sync) {}
 
 BooleanQuery::~BooleanQuery() {
 }
 
-bool BooleanQuery::Process(bool did_finish) {
-  if (!AreAllResultsAvailable()) {
-    // Must return true to avoid generating an error at the command
-    // buffer level.
-    return true;
-  }
+void BooleanQuery::Process(bool did_finish) {
+  if (!AreAllResultsAvailable())
+    return;
   for (const GLuint& service_id : service_ids_) {
     GLuint result = 0;
     glGetQueryObjectuiv(service_id, GL_QUERY_RESULT_EXT, &result);
-    if (result != 0)
-      return MarkAsCompleted(1);
+    if (result != 0) {
+      MarkAsCompleted(1);
+      return;
+    }
   }
-  return MarkAsCompleted(0);
+  MarkAsCompleted(0);
 }
 
 class SummedIntegerQuery : public AbstractIntegerQuery {
  public:
   SummedIntegerQuery(QueryManager* manager,
                      GLenum target,
-                     int32_t shm_id,
-                     uint32_t shm_offset);
-  bool Process(bool did_finish) override;
+                     scoped_refptr<gpu::Buffer> buffer,
+                     QuerySync* sync);
+  void Process(bool did_finish) override;
 
  protected:
   ~SummedIntegerQuery() override;
@@ -162,41 +159,38 @@
 
 SummedIntegerQuery::SummedIntegerQuery(QueryManager* manager,
                                        GLenum target,
-                                       int32_t shm_id,
-                                       uint32_t shm_offset)
-    : AbstractIntegerQuery(manager, target, shm_id, shm_offset) {}
+                                       scoped_refptr<gpu::Buffer> buffer,
+                                       QuerySync* sync)
+    : AbstractIntegerQuery(manager, target, std::move(buffer), sync) {}
 
 SummedIntegerQuery::~SummedIntegerQuery() {
 }
 
-bool SummedIntegerQuery::Process(bool did_finish) {
-  if (!AreAllResultsAvailable()) {
-    // Must return true to avoid generating an error at the command
-    // buffer level.
-    return true;
-  }
+void SummedIntegerQuery::Process(bool did_finish) {
+  if (!AreAllResultsAvailable())
+    return;
   GLuint summed_result = 0;
   for (const GLuint& service_id : service_ids_) {
     GLuint result = 0;
     glGetQueryObjectuiv(service_id, GL_QUERY_RESULT_EXT, &result);
     summed_result += result;
   }
-  return MarkAsCompleted(summed_result);
+  MarkAsCompleted(summed_result);
 }
 
 class CommandsIssuedQuery : public QueryManager::Query {
  public:
   CommandsIssuedQuery(QueryManager* manager,
                       GLenum target,
-                      int32_t shm_id,
-                      uint32_t shm_offset);
+                      scoped_refptr<gpu::Buffer> buffer,
+                      QuerySync* sync);
 
-  bool Begin() override;
-  bool End(base::subtle::Atomic32 submit_count) override;
-  bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+  void Begin() override;
+  void End(base::subtle::Atomic32 submit_count) override;
+  void QueryCounter(base::subtle::Atomic32 submit_count) override;
   void Pause() override;
   void Resume() override;
-  bool Process(bool did_finish) override;
+  void Process(bool did_finish) override;
   void Destroy(bool have_context) override;
 
  protected:
@@ -208,14 +202,13 @@
 
 CommandsIssuedQuery::CommandsIssuedQuery(QueryManager* manager,
                                          GLenum target,
-                                         int32_t shm_id,
-                                         uint32_t shm_offset)
-    : Query(manager, target, shm_id, shm_offset) {}
+                                         scoped_refptr<gpu::Buffer> buffer,
+                                         QuerySync* sync)
+    : Query(manager, target, std::move(buffer), sync) {}
 
-bool CommandsIssuedQuery::Begin() {
+void CommandsIssuedQuery::Begin() {
   MarkAsActive();
   begin_time_ = base::TimeTicks::Now();
-  return true;
 }
 
 void CommandsIssuedQuery::Pause() {
@@ -226,20 +219,18 @@
   MarkAsActive();
 }
 
-bool CommandsIssuedQuery::End(base::subtle::Atomic32 submit_count) {
+void CommandsIssuedQuery::End(base::subtle::Atomic32 submit_count) {
   const base::TimeDelta elapsed = base::TimeTicks::Now() - begin_time_;
   MarkAsPending(submit_count);
-  return MarkAsCompleted(elapsed.InMicroseconds());
+  MarkAsCompleted(elapsed.InMicroseconds());
 }
 
-bool CommandsIssuedQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
+void CommandsIssuedQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
   NOTREACHED();
-  return false;
 }
 
-bool CommandsIssuedQuery::Process(bool did_finish) {
+void CommandsIssuedQuery::Process(bool did_finish) {
   NOTREACHED();
-  return true;
 }
 
 void CommandsIssuedQuery::Destroy(bool /* have_context */) {
@@ -255,15 +246,15 @@
  public:
   CommandLatencyQuery(QueryManager* manager,
                       GLenum target,
-                      int32_t shm_id,
-                      uint32_t shm_offset);
+                      scoped_refptr<gpu::Buffer> buffer,
+                      QuerySync* sync);
 
-  bool Begin() override;
-  bool End(base::subtle::Atomic32 submit_count) override;
-  bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+  void Begin() override;
+  void End(base::subtle::Atomic32 submit_count) override;
+  void QueryCounter(base::subtle::Atomic32 submit_count) override;
   void Pause() override;
   void Resume() override;
-  bool Process(bool did_finish) override;
+  void Process(bool did_finish) override;
   void Destroy(bool have_context) override;
 
  protected:
@@ -272,13 +263,12 @@
 
 CommandLatencyQuery::CommandLatencyQuery(QueryManager* manager,
                                          GLenum target,
-                                         int32_t shm_id,
-                                         uint32_t shm_offset)
-    : Query(manager, target, shm_id, shm_offset) {}
+                                         scoped_refptr<gpu::Buffer> buffer,
+                                         QuerySync* sync)
+    : Query(manager, target, std::move(buffer), sync) {}
 
-bool CommandLatencyQuery::Begin() {
+void CommandLatencyQuery::Begin() {
   MarkAsActive();
-  return true;
 }
 
 void CommandLatencyQuery::Pause() {
@@ -289,20 +279,18 @@
   MarkAsActive();
 }
 
-bool CommandLatencyQuery::End(base::subtle::Atomic32 submit_count) {
-    base::TimeDelta now = base::TimeTicks::Now() - base::TimeTicks();
-    MarkAsPending(submit_count);
-    return MarkAsCompleted(now.InMicroseconds());
+void CommandLatencyQuery::End(base::subtle::Atomic32 submit_count) {
+  base::TimeDelta now = base::TimeTicks::Now() - base::TimeTicks();
+  MarkAsPending(submit_count);
+  MarkAsCompleted(now.InMicroseconds());
 }
 
-bool CommandLatencyQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
+void CommandLatencyQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
   NOTREACHED();
-  return false;
 }
 
-bool CommandLatencyQuery::Process(bool did_finish) {
+void CommandLatencyQuery::Process(bool did_finish) {
   NOTREACHED();
-  return true;
 }
 
 void CommandLatencyQuery::Destroy(bool /* have_context */) {
@@ -321,35 +309,31 @@
  public:
   AsyncReadPixelsCompletedQuery(QueryManager* manager,
                                 GLenum target,
-                                int32_t shm_id,
-                                uint32_t shm_offset);
+                                scoped_refptr<gpu::Buffer> buffer,
+                                QuerySync* sync);
 
-  bool Begin() override;
-  bool End(base::subtle::Atomic32 submit_count) override;
-  bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+  void Begin() override;
+  void End(base::subtle::Atomic32 submit_count) override;
+  void QueryCounter(base::subtle::Atomic32 submit_count) override;
   void Pause() override;
   void Resume() override;
-  bool Process(bool did_finish) override;
+  void Process(bool did_finish) override;
   void Destroy(bool have_context) override;
 
  protected:
   void Complete();
   ~AsyncReadPixelsCompletedQuery() override;
-
- private:
-  bool complete_result_;
 };
 
 AsyncReadPixelsCompletedQuery::AsyncReadPixelsCompletedQuery(
     QueryManager* manager,
     GLenum target,
-    int32_t shm_id,
-    uint32_t shm_offset)
-    : Query(manager, target, shm_id, shm_offset), complete_result_(false) {}
+    scoped_refptr<gpu::Buffer> buffer,
+    QuerySync* sync)
+    : Query(manager, target, std::move(buffer), sync) {}
 
-bool AsyncReadPixelsCompletedQuery::Begin() {
+void AsyncReadPixelsCompletedQuery::Begin() {
   MarkAsActive();
-  return true;
 }
 
 void AsyncReadPixelsCompletedQuery::Pause() {
@@ -360,29 +344,24 @@
   MarkAsActive();
 }
 
-bool AsyncReadPixelsCompletedQuery::End(base::subtle::Atomic32 submit_count) {
-  if (!AddToPendingQueue(submit_count)) {
-    return false;
-  }
+void AsyncReadPixelsCompletedQuery::End(base::subtle::Atomic32 submit_count) {
+  MarkAsPending(submit_count);
   manager()->decoder()->WaitForReadPixels(
       base::Bind(&AsyncReadPixelsCompletedQuery::Complete,
                  AsWeakPtr()));
-
-  return Process(false);
 }
 
-bool AsyncReadPixelsCompletedQuery::QueryCounter(
+void AsyncReadPixelsCompletedQuery::QueryCounter(
     base::subtle::Atomic32 submit_count) {
   NOTREACHED();
-  return false;
 }
 
 void AsyncReadPixelsCompletedQuery::Complete() {
-  complete_result_ = MarkAsCompleted(1);
+  MarkAsCompleted(1);
 }
 
-bool AsyncReadPixelsCompletedQuery::Process(bool did_finish) {
-  return !IsFinished() || complete_result_;
+void AsyncReadPixelsCompletedQuery::Process(bool did_finish) {
+  NOTREACHED();
 }
 
 void AsyncReadPixelsCompletedQuery::Destroy(bool /* have_context */) {
@@ -399,15 +378,15 @@
  public:
   GetErrorQuery(QueryManager* manager,
                 GLenum target,
-                int32_t shm_id,
-                uint32_t shm_offset);
+                scoped_refptr<gpu::Buffer> buffer,
+                QuerySync* sync);
 
-  bool Begin() override;
-  bool End(base::subtle::Atomic32 submit_count) override;
-  bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+  void Begin() override;
+  void End(base::subtle::Atomic32 submit_count) override;
+  void QueryCounter(base::subtle::Atomic32 submit_count) override;
   void Pause() override;
   void Resume() override;
-  bool Process(bool did_finish) override;
+  void Process(bool did_finish) override;
   void Destroy(bool have_context) override;
 
  protected:
@@ -418,13 +397,12 @@
 
 GetErrorQuery::GetErrorQuery(QueryManager* manager,
                              GLenum target,
-                             int32_t shm_id,
-                             uint32_t shm_offset)
-    : Query(manager, target, shm_id, shm_offset) {}
+                             scoped_refptr<gpu::Buffer> buffer,
+                             QuerySync* sync)
+    : Query(manager, target, std::move(buffer), sync) {}
 
-bool GetErrorQuery::Begin() {
+void GetErrorQuery::Begin() {
   MarkAsActive();
-  return true;
 }
 
 void GetErrorQuery::Pause() {
@@ -435,19 +413,17 @@
   MarkAsActive();
 }
 
-bool GetErrorQuery::End(base::subtle::Atomic32 submit_count) {
+void GetErrorQuery::End(base::subtle::Atomic32 submit_count) {
   MarkAsPending(submit_count);
-  return MarkAsCompleted(manager()->decoder()->GetErrorState()->GetGLError());
+  MarkAsCompleted(manager()->decoder()->GetErrorState()->GetGLError());
 }
 
-bool GetErrorQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
+void GetErrorQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
   NOTREACHED();
-  return false;
 }
 
-bool GetErrorQuery::Process(bool did_finish) {
+void GetErrorQuery::Process(bool did_finish) {
   NOTREACHED();
-  return true;
 }
 
 void GetErrorQuery::Destroy(bool /* have_context */) {
@@ -463,16 +439,16 @@
  public:
   CommandsCompletedQuery(QueryManager* manager,
                          GLenum target,
-                         int32_t shm_id,
-                         uint32_t shm_offset);
+                         scoped_refptr<gpu::Buffer> buffer,
+                         QuerySync* sync);
 
   // Overridden from QueryManager::Query:
-  bool Begin() override;
-  bool End(base::subtle::Atomic32 submit_count) override;
-  bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+  void Begin() override;
+  void End(base::subtle::Atomic32 submit_count) override;
+  void QueryCounter(base::subtle::Atomic32 submit_count) override;
   void Pause() override;
   void Resume() override;
-  bool Process(bool did_finish) override;
+  void Process(bool did_finish) override;
   void Destroy(bool have_context) override;
 
  protected:
@@ -483,16 +459,16 @@
   base::TimeTicks begin_time_;
 };
 
-CommandsCompletedQuery::CommandsCompletedQuery(QueryManager* manager,
-                                               GLenum target,
-                                               int32_t shm_id,
-                                               uint32_t shm_offset)
-    : Query(manager, target, shm_id, shm_offset) {}
+CommandsCompletedQuery::CommandsCompletedQuery(
+    QueryManager* manager,
+    GLenum target,
+    scoped_refptr<gpu::Buffer> buffer,
+    QuerySync* sync)
+    : Query(manager, target, std::move(buffer), sync) {}
 
-bool CommandsCompletedQuery::Begin() {
+void CommandsCompletedQuery::Begin() {
   MarkAsActive();
   begin_time_ = base::TimeTicks::Now();
-  return true;
 }
 
 void CommandsCompletedQuery::Pause() {
@@ -503,7 +479,7 @@
   MarkAsActive();
 }
 
-bool CommandsCompletedQuery::End(base::subtle::Atomic32 submit_count) {
+void CommandsCompletedQuery::End(base::subtle::Atomic32 submit_count) {
   if (fence_ && fence_->ResetSupported()) {
     fence_->ResetState();
   }
@@ -511,23 +487,22 @@
     fence_.reset(gl::GLFence::Create());
   }
   DCHECK(fence_);
-  return AddToPendingQueue(submit_count);
+  AddToPendingQueue(submit_count);
 }
 
-bool CommandsCompletedQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
+void CommandsCompletedQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
   NOTREACHED();
-  return false;
 }
 
-bool CommandsCompletedQuery::Process(bool did_finish) {
+void CommandsCompletedQuery::Process(bool did_finish) {
   // Note: |did_finish| guarantees that the GPU has passed the fence but
   // we cannot assume that GLFence::HasCompleted() will return true yet as
   // that's not guaranteed by all GLFence implementations.
   if (!did_finish && fence_ && !fence_->HasCompleted())
-    return true;
+    return;
 
   const base::TimeDelta elapsed = base::TimeTicks::Now() - begin_time_;
-  return MarkAsCompleted(elapsed.InMicroseconds());
+  MarkAsCompleted(elapsed.InMicroseconds());
 }
 
 void CommandsCompletedQuery::Destroy(bool have_context) {
@@ -543,16 +518,16 @@
  public:
   TimeElapsedQuery(QueryManager* manager,
                    GLenum target,
-                   int32_t shm_id,
-                   uint32_t shm_offset);
+                   scoped_refptr<gpu::Buffer> buffer,
+                   QuerySync* sync);
 
   // Overridden from QueryManager::Query:
-  bool Begin() override;
-  bool End(base::subtle::Atomic32 submit_count) override;
-  bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+  void Begin() override;
+  void End(base::subtle::Atomic32 submit_count) override;
+  void QueryCounter(base::subtle::Atomic32 submit_count) override;
   void Pause() override;
   void Resume() override;
-  bool Process(bool did_finish) override;
+  void Process(bool did_finish) override;
   void Destroy(bool have_context) override;
 
  protected:
@@ -564,27 +539,25 @@
 
 TimeElapsedQuery::TimeElapsedQuery(QueryManager* manager,
                                    GLenum target,
-                                   int32_t shm_id,
-                                   uint32_t shm_offset)
-    : Query(manager, target, shm_id, shm_offset),
+                                   scoped_refptr<gpu::Buffer> buffer,
+                                   QuerySync* sync)
+    : Query(manager, target, std::move(buffer), sync),
       gpu_timer_(manager->CreateGPUTimer(true)) {}
 
-bool TimeElapsedQuery::Begin() {
+void TimeElapsedQuery::Begin() {
   // Reset the disjoint value before the query begins if it is safe.
   SafelyResetDisjointValue();
   MarkAsActive();
   gpu_timer_->Start();
-  return true;
 }
 
-bool TimeElapsedQuery::End(base::subtle::Atomic32 submit_count) {
+void TimeElapsedQuery::End(base::subtle::Atomic32 submit_count) {
   gpu_timer_->End();
-  return AddToPendingQueue(submit_count);
+  AddToPendingQueue(submit_count);
 }
 
-bool TimeElapsedQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
+void TimeElapsedQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
   NOTREACHED();
-  return false;
 }
 
 void TimeElapsedQuery::Pause() {
@@ -595,9 +568,9 @@
   MarkAsActive();
 }
 
-bool TimeElapsedQuery::Process(bool did_finish) {
+void TimeElapsedQuery::Process(bool did_finish) {
   if (!gpu_timer_->IsAvailable())
-    return true;
+    return;
 
   // Make sure disjoint value is up to date. This disjoint check is the only one
   // that needs to be done to validate that this query is valid. If a disjoint
@@ -607,7 +580,7 @@
 
   const uint64_t nano_seconds = gpu_timer_->GetDeltaElapsed() *
                                 base::Time::kNanosecondsPerMicrosecond;
-  return MarkAsCompleted(nano_seconds);
+  MarkAsCompleted(nano_seconds);
 }
 
 void TimeElapsedQuery::Destroy(bool have_context) {
@@ -620,16 +593,16 @@
  public:
   TimeStampQuery(QueryManager* manager,
                  GLenum target,
-                 int32_t shm_id,
-                 uint32_t shm_offset);
+                 scoped_refptr<gpu::Buffer> buffer,
+                 QuerySync* sync);
 
   // Overridden from QueryManager::Query:
-  bool Begin() override;
-  bool End(base::subtle::Atomic32 submit_count) override;
-  bool QueryCounter(base::subtle::Atomic32 submit_count) override;
+  void Begin() override;
+  void End(base::subtle::Atomic32 submit_count) override;
+  void QueryCounter(base::subtle::Atomic32 submit_count) override;
   void Pause() override;
   void Resume() override;
-  bool Process(bool did_finish) override;
+  void Process(bool did_finish) override;
   void Destroy(bool have_context) override;
 
  protected:
@@ -641,19 +614,17 @@
 
 TimeStampQuery::TimeStampQuery(QueryManager* manager,
                                GLenum target,
-                               int32_t shm_id,
-                               uint32_t shm_offset)
-    : Query(manager, target, shm_id, shm_offset),
+                               scoped_refptr<gpu::Buffer> buffer,
+                               QuerySync* sync)
+    : Query(manager, target, std::move(buffer), sync),
       gpu_timer_(manager->CreateGPUTimer(false)) {}
 
-bool TimeStampQuery::Begin() {
+void TimeStampQuery::Begin() {
   NOTREACHED();
-  return false;
 }
 
-bool TimeStampQuery::End(base::subtle::Atomic32 submit_count) {
+void TimeStampQuery::End(base::subtle::Atomic32 submit_count) {
   NOTREACHED();
-  return false;
 }
 
 void TimeStampQuery::Pause() {
@@ -664,7 +635,7 @@
   MarkAsActive();
 }
 
-bool TimeStampQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
+void TimeStampQuery::QueryCounter(base::subtle::Atomic32 submit_count) {
   // Reset the disjoint value before the query begins if it is safe.
   SafelyResetDisjointValue();
   MarkAsActive();
@@ -673,12 +644,12 @@
   BeginContinualDisjointUpdate();
 
   gpu_timer_->QueryTimeStamp();
-  return AddToPendingQueue(submit_count);
+  AddToPendingQueue(submit_count);
 }
 
-bool TimeStampQuery::Process(bool did_finish) {
+void TimeStampQuery::Process(bool did_finish) {
   if (!gpu_timer_->IsAvailable())
-    return true;
+    return;
 
   // Make sure disjoint value is up to date. This disjoint check is the only one
   // that needs to be done to validate that this query is valid. If a disjoint
@@ -692,7 +663,7 @@
   DCHECK(start == end);
 
   const uint64_t nano_seconds = start * base::Time::kNanosecondsPerMicrosecond;
-  return MarkAsCompleted(nano_seconds);
+  MarkAsCompleted(nano_seconds);
 }
 
 void TimeStampQuery::Destroy(bool have_context) {
@@ -741,7 +712,6 @@
 void QueryManager::Destroy(bool have_context) {
   active_queries_.clear();
   pending_queries_.clear();
-  pending_transfer_queries_.clear();
   while (!queries_.empty()) {
     Query* query = queries_.begin()->second.get();
     query->Destroy(have_context);
@@ -767,43 +737,44 @@
   return error::kNoError;
 }
 
-QueryManager::Query* QueryManager::CreateQuery(GLenum target,
-                                               GLuint client_id,
-                                               int32_t shm_id,
-                                               uint32_t shm_offset) {
+QueryManager::Query* QueryManager::CreateQuery(
+    GLenum target,
+    GLuint client_id,
+    scoped_refptr<gpu::Buffer> buffer,
+    QuerySync* sync) {
   scoped_refptr<Query> query;
   switch (target) {
     case GL_COMMANDS_ISSUED_CHROMIUM:
-      query = new CommandsIssuedQuery(this, target, shm_id, shm_offset);
+      query = new CommandsIssuedQuery(this, target, std::move(buffer), sync);
       break;
     case GL_LATENCY_QUERY_CHROMIUM:
-      query = new CommandLatencyQuery(this, target, shm_id, shm_offset);
+      query = new CommandLatencyQuery(this, target, std::move(buffer), sync);
       break;
     case GL_ASYNC_PIXEL_PACK_COMPLETED_CHROMIUM:
-      query = new AsyncReadPixelsCompletedQuery(
-          this, target, shm_id, shm_offset);
+      query = new AsyncReadPixelsCompletedQuery(this, target, std::move(buffer),
+                                                sync);
       break;
     case GL_GET_ERROR_QUERY_CHROMIUM:
-      query = new GetErrorQuery(this, target, shm_id, shm_offset);
+      query = new GetErrorQuery(this, target, std::move(buffer), sync);
       break;
     case GL_COMMANDS_COMPLETED_CHROMIUM:
-      query = new CommandsCompletedQuery(this, target, shm_id, shm_offset);
+      query = new CommandsCompletedQuery(this, target, std::move(buffer), sync);
       break;
     case GL_TIME_ELAPSED:
-      query = new TimeElapsedQuery(this, target, shm_id, shm_offset);
+      query = new TimeElapsedQuery(this, target, std::move(buffer), sync);
       break;
     case GL_TIMESTAMP:
-      query = new TimeStampQuery(this, target, shm_id, shm_offset);
+      query = new TimeStampQuery(this, target, std::move(buffer), sync);
       break;
     case GL_ANY_SAMPLES_PASSED:
     case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
-      query = new BooleanQuery(this, target, shm_id, shm_offset);
+      query = new BooleanQuery(this, target, std::move(buffer), sync);
       break;
     case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
-      query = new SummedIntegerQuery(this, target, shm_id, shm_offset);
+      query = new SummedIntegerQuery(this, target, std::move(buffer), sync);
       break;
     case GL_SAMPLES_PASSED:
-      query = new SummedIntegerQuery(this, target, shm_id, shm_offset);
+      query = new SummedIntegerQuery(this, target, std::move(buffer), sync);
       break;
     default: {
       NOTREACHED();
@@ -935,12 +906,12 @@
 
 QueryManager::Query::Query(QueryManager* manager,
                            GLenum target,
-                           int32_t shm_id,
-                           uint32_t shm_offset)
+                           scoped_refptr<gpu::Buffer> buffer,
+                           QuerySync* sync)
     : manager_(manager),
       target_(target),
-      shm_id_(shm_id),
-      shm_offset_(shm_offset),
+      buffer_(std::move(buffer)),
+      sync_(sync),
       submit_count_(0),
       query_state_(kQueryState_Initialize),
       deleted_(false) {
@@ -974,93 +945,46 @@
   }
 }
 
-bool QueryManager::Query::MarkAsCompleted(uint64_t result) {
+void QueryManager::Query::MarkAsCompleted(uint64_t result) {
   UnmarkAsPending();
-  QuerySync* sync = manager_->decoder_->GetSharedMemoryAs<QuerySync*>(
-      shm_id_, shm_offset_, sizeof(*sync));
-  if (!sync) {
-    return false;
-  }
 
-  sync->result = result;
-  base::subtle::Release_Store(&sync->process_count, submit_count_);
-
-  return true;
+  sync_->result = result;
+  base::subtle::Release_Store(&sync_->process_count, submit_count_);
+  RunCallbacks();
 }
 
-bool QueryManager::ProcessPendingQueries(bool did_finish) {
+void QueryManager::ProcessPendingQueries(bool did_finish) {
   while (!pending_queries_.empty()) {
     Query* query = pending_queries_.front().get();
-    if (!query->Process(did_finish)) {
-      return false;
-    }
+    query->Process(did_finish);
     if (query->IsPending()) {
       break;
     }
-    query->RunCallbacks();
     pending_queries_.pop_front();
   }
   // If glFinish() has been called, all of our queries should be completed.
   DCHECK(!did_finish || pending_queries_.empty());
-
-  return true;
 }
 
 bool QueryManager::HavePendingQueries() {
   return !pending_queries_.empty();
 }
 
-bool QueryManager::ProcessPendingTransferQueries() {
-  while (!pending_transfer_queries_.empty()) {
-    Query* query = pending_transfer_queries_.front().get();
-    if (!query->Process(false)) {
-      return false;
-    }
-    if (query->IsPending()) {
-      break;
-    }
-    query->RunCallbacks();
-    pending_transfer_queries_.pop_front();
-  }
-
-  return true;
-}
-
-bool QueryManager::HavePendingTransferQueries() {
-  return !pending_transfer_queries_.empty();
-}
-
 void QueryManager::ProcessFrameBeginUpdates() {
   if (update_disjoints_continually_)
     UpdateDisjointValue();
 }
 
-bool QueryManager::AddPendingQuery(Query* query,
+void QueryManager::AddPendingQuery(Query* query,
                                    base::subtle::Atomic32 submit_count) {
   DCHECK(query);
   DCHECK(!query->IsDeleted());
-  if (!RemovePendingQuery(query)) {
-    return false;
-  }
+  RemovePendingQuery(query);
   query->MarkAsPending(submit_count);
   pending_queries_.push_back(query);
-  return true;
 }
 
-bool QueryManager::AddPendingTransferQuery(
-    Query* query,
-    base::subtle::Atomic32 submit_count) {
-  DCHECK(query);
-  DCHECK(!query->IsDeleted());
-  if (!RemovePendingQuery(query)) {
-    return false;
-  }
-  query->MarkAsPending(submit_count);
-  pending_transfer_queries_.push_back(query);
-  return true;
-}
-
-bool QueryManager::RemovePendingQuery(Query* query) {
+void QueryManager::RemovePendingQuery(Query* query) {
   DCHECK(query);
   if (query->IsPending()) {
     // TODO(gman): Speed this up if this is a common operation. This would only
@@ -1073,38 +997,20 @@
         break;
       }
     }
-    for (QueryQueue::iterator it = pending_transfer_queries_.begin();
-         it != pending_transfer_queries_.end(); ++it) {
-      if (it->get() == query) {
-        pending_transfer_queries_.erase(it);
-        break;
-      }
-    }
-    if (!query->MarkAsCompleted(0)) {
-      return false;
-    }
+    query->MarkAsCompleted(0);
   }
-  return true;
 }
 
-bool QueryManager::BeginQuery(Query* query) {
+void QueryManager::BeginQuery(Query* query) {
   DCHECK(query);
-  if (!RemovePendingQuery(query)) {
-    return false;
-  }
-  if (query->Begin()) {
-    active_queries_[query->target()] = query;
-    return true;
-  }
-
-  return false;
+  RemovePendingQuery(query);
+  query->Begin();
+  active_queries_[query->target()] = query;
 }
 
-bool QueryManager::EndQuery(Query* query, base::subtle::Atomic32 submit_count) {
+void QueryManager::EndQuery(Query* query, base::subtle::Atomic32 submit_count) {
   DCHECK(query);
-  if (!RemovePendingQuery(query)) {
-    return false;
-  }
+  RemovePendingQuery(query);
 
   // Remove from active query map if it is active.
   ActiveQueryMap::iterator active_it = active_queries_.find(query->target());
@@ -1112,16 +1018,14 @@
   DCHECK(query == active_it->second.get());
   active_queries_.erase(active_it);
 
-  return query->End(submit_count);
+  query->End(submit_count);
 }
 
-bool QueryManager::QueryCounter(
-    Query* query, base::subtle::Atomic32 submit_count) {
+void QueryManager::QueryCounter(Query* query,
+                                base::subtle::Atomic32 submit_count) {
   DCHECK(query);
-  if (!RemovePendingQuery(query)) {
-    return false;
-  }
-  return query->QueryCounter(submit_count);
+  RemovePendingQuery(query);
+  query->QueryCounter(submit_count);
 }
 
 void QueryManager::PauseQueries() {
diff --git a/gpu/command_buffer/service/query_manager.h b/gpu/command_buffer/service/query_manager.h
index a132c6aa..e230b22d 100644
--- a/gpu/command_buffer/service/query_manager.h
+++ b/gpu/command_buffer/service/query_manager.h
@@ -40,8 +40,8 @@
    public:
     Query(QueryManager* manager,
           GLenum target,
-          int32_t shm_id,
-          uint32_t shm_offset);
+          scoped_refptr<gpu::Buffer> buffer,
+          QuerySync* sync);
 
     GLenum target() const {
       return target_;
@@ -71,21 +71,15 @@
       return query_state_ == kQueryState_Finished;
     }
 
-    int32_t shm_id() const { return shm_id_; }
+    const QuerySync* sync() const { return sync_; }
 
-    uint32_t shm_offset() const { return shm_offset_; }
+    virtual void Begin() = 0;
 
-    // Returns false if shared memory for sync is invalid.
-    virtual bool Begin() = 0;
+    virtual void End(base::subtle::Atomic32 submit_count) = 0;
 
-    // Returns false if shared memory for sync is invalid.
-    virtual bool End(base::subtle::Atomic32 submit_count) = 0;
+    virtual void QueryCounter(base::subtle::Atomic32 submit_count) = 0;
 
-    // Returns false if shared memory for sync is invalid.
-    virtual bool QueryCounter(base::subtle::Atomic32 submit_count) = 0;
-
-    // Returns false if shared memory for sync is invalid.
-    virtual bool Process(bool did_finish) = 0;
+    virtual void Process(bool did_finish) = 0;
 
     // Pauses active query to be resumed later.
     virtual void Pause() = 0;
@@ -126,22 +120,15 @@
       submit_count_ = submit_count;
     }
 
-    // Returns false if shared memory for sync is invalid.
-    bool MarkAsCompleted(uint64_t result);
+    void MarkAsCompleted(uint64_t result);
 
     void UnmarkAsPending() {
       DCHECK(query_state_ == kQueryState_Pending);
       query_state_ = kQueryState_Finished;
     }
 
-    // Returns false if shared memory for sync is invalid.
-    bool AddToPendingQueue(base::subtle::Atomic32 submit_count) {
-      return manager_->AddPendingQuery(this, submit_count);
-    }
-
-    // Returns false if shared memory for sync is invalid.
-    bool AddToPendingTransferQueue(base::subtle::Atomic32 submit_count) {
-      return manager_->AddPendingTransferQuery(this, submit_count);
+    void AddToPendingQueue(base::subtle::Atomic32 submit_count) {
+      manager_->AddPendingQuery(this, submit_count);
     }
 
     void BeginQueryHelper(GLenum target, GLuint id) {
@@ -179,9 +166,11 @@
     // The type of query.
     GLenum target_;
 
-    // The shared memory used with this Query.
-    int32_t shm_id_;
-    uint32_t shm_offset_;
+    // The shared memory used with this Query. We keep a reference to the Buffer
+    // to ensure it doesn't get released until we wrote results. sync_ points to
+    // memory inside buffer_.
+    scoped_refptr<gpu::Buffer> buffer_;
+    QuerySync* sync_;
 
     // Count to set process count do when completed.
     base::subtle::Atomic32 submit_count_;
@@ -216,8 +205,8 @@
   // Creates a Query for the given query.
   Query* CreateQuery(GLenum target,
                      GLuint client_id,
-                     int32_t shm_id,
-                     uint32_t shm_offset);
+                     scoped_refptr<gpu::Buffer> buffer,
+                     QuerySync* sync);
 
   // Gets the query info for the given query.
   Query* GetQuery(GLuint client_id);
@@ -229,13 +218,13 @@
   void RemoveQuery(GLuint client_id);
 
   // Returns false if any query is pointing to invalid shared memory.
-  bool BeginQuery(Query* query);
+  void BeginQuery(Query* query);
 
   // Returns false if any query is pointing to invalid shared memory.
-  bool EndQuery(Query* query, base::subtle::Atomic32 submit_count);
+  void EndQuery(Query* query, base::subtle::Atomic32 submit_count);
 
   // Returns false if any query is pointing to invalid shared memory.
-  bool QueryCounter(Query* query, base::subtle::Atomic32 submit_count);
+  void QueryCounter(Query* query, base::subtle::Atomic32 submit_count);
 
   void PauseQueries();
   void ResumeQueries();
@@ -243,18 +232,11 @@
   // Processes pending queries. Returns false if any queries are pointing
   // to invalid shared memory. |did_finish| is true if this is called as
   // a result of calling glFinish().
-  bool ProcessPendingQueries(bool did_finish);
+  void ProcessPendingQueries(bool did_finish);
 
   // True if there are pending queries.
   bool HavePendingQueries();
 
-  // Processes pending transfer queries. Returns false if any queries are
-  // pointing to invalid shared memory.
-  bool ProcessPendingTransferQueries();
-
-  // True if there are pending transfer queries.
-  bool HavePendingTransferQueries();
-
   // Do any updates we need to do when the frame has begun.
   void ProcessFrameBeginUpdates();
 
@@ -279,16 +261,11 @@
 
   // Adds to queue of queries waiting for completion.
   // Returns false if any query is pointing to invalid shared memory.
-  bool AddPendingQuery(Query* query, base::subtle::Atomic32 submit_count);
-
-  // Adds to queue of transfer queries waiting for completion.
-  // Returns false if any query is pointing to invalid shared memory.
-  bool AddPendingTransferQuery(Query* query,
-                               base::subtle::Atomic32 submit_count);
+  void AddPendingQuery(Query* query, base::subtle::Atomic32 submit_count);
 
   // Removes a query from the queue of pending queries.
   // Returns false if any query is pointing to invalid shared memory.
-  bool RemovePendingQuery(Query* query);
+  void RemovePendingQuery(Query* query);
 
   // Returns a target used for the underlying GL extension
   // used to emulate a query.
@@ -335,9 +312,6 @@
   typedef std::deque<scoped_refptr<Query> > QueryQueue;
   QueryQueue pending_queries_;
 
-  // Async pixel transfer queries waiting for completion.
-  QueryQueue pending_transfer_queries_;
-
   scoped_refptr<gl::GPUTimingClient> gpu_timing_client_;
 
   DISALLOW_COPY_AND_ASSIGN(QueryManager);
diff --git a/gpu/command_buffer/service/query_manager_unittest.cc b/gpu/command_buffer/service/query_manager_unittest.cc
index e582bf1..8c6f6ba 100644
--- a/gpu/command_buffer/service/query_manager_unittest.cc
+++ b/gpu/command_buffer/service/query_manager_unittest.cc
@@ -84,10 +84,29 @@
                                    int32_t shm_id,
                                    uint32_t shm_offset,
                                    GLuint service_id) {
-    EXPECT_CALL(*gl_, GenQueries(1, _))
-        .WillOnce(SetArgPointee<1>(service_id))
-        .RetiresOnSaturation();
-    return manager_->CreateQuery(target, client_id, shm_id, shm_offset);
+    return CreateQueryOnManager(manager_.get(), target, client_id, shm_id,
+                                shm_offset, service_id);
+  }
+
+  QueryManager::Query* CreateQueryOnManager(QueryManager* manager,
+                                            GLenum target,
+                                            GLuint client_id,
+                                            int32_t shm_id,
+                                            uint32_t shm_offset,
+                                            GLuint service_id) {
+    if (service_id) {
+      EXPECT_CALL(*gl_, GenQueries(1, _))
+          .WillOnce(SetArgPointee<1>(service_id))
+          .RetiresOnSaturation();
+    }
+    scoped_refptr<gpu::Buffer> buffer = decoder_->GetSharedMemoryBuffer(shm_id);
+    if (!buffer)
+      return nullptr;
+    QuerySync* sync = static_cast<QuerySync*>(
+        buffer->GetDataAddress(shm_offset, sizeof(QuerySync)));
+    if (!sync)
+      return nullptr;
+    return manager->CreateQuery(target, client_id, std::move(buffer), sync);
   }
 
   void QueueQuery(QueryManager::Query* query,
@@ -99,8 +118,8 @@
     EXPECT_CALL(*gl_, EndQuery(query->target()))
         .Times(1)
         .RetiresOnSaturation();
-    EXPECT_TRUE(manager_->BeginQuery(query));
-    EXPECT_TRUE(manager_->EndQuery(query, submit_count));
+    manager_->BeginQuery(query);
+    manager_->EndQuery(query, submit_count);
   }
 
   std::unique_ptr<FakeCommandBufferServiceBase> command_buffer_service_;
@@ -190,8 +209,6 @@
   EXPECT_FALSE(query->IsDeleted());
   EXPECT_FALSE(query->IsPending());
   EXPECT_EQ(kTarget, query->target());
-  EXPECT_EQ(shared_memory_id_, query->shm_id());
-  EXPECT_EQ(kSharedMemoryOffset, query->shm_offset());
 }
 
 TEST_F(QueryManagerTest, ProcessPendingQuery) {
@@ -202,7 +219,7 @@
   const GLuint kResult = 1;
 
   // Check nothing happens if there are no pending queries.
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->ProcessPendingQueries(false);
 
   // Create Query.
   scoped_refptr<QueryManager::Query> query(
@@ -227,7 +244,7 @@
               GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
       .WillOnce(SetArgPointee<2>(0))
       .RetiresOnSaturation();
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->ProcessPendingQueries(false);
   EXPECT_TRUE(query->IsPending());
   EXPECT_EQ(0, sync->process_count);
   EXPECT_EQ(0u, sync->result);
@@ -241,7 +258,7 @@
   EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _))
       .WillOnce(SetArgPointee<2>(kResult))
       .RetiresOnSaturation();
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->ProcessPendingQueries(false);
   EXPECT_FALSE(query->IsPending());
   EXPECT_EQ(kSubmitCount, sync->process_count);
   EXPECT_EQ(kResult, sync->result);
@@ -249,7 +266,7 @@
 
   // Process with no queries.
   // Expect no GL commands/
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->ProcessPendingQueries(false);
 }
 
 TEST_F(QueryManagerTest, ProcessPendingQueries) {
@@ -324,7 +341,7 @@
         *gl_, GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
         .WillOnce(SetArgPointee<2>(0))
         .RetiresOnSaturation();
-    EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+    manager_->ProcessPendingQueries(false);
   }
   EXPECT_FALSE(query1->IsPending());
   EXPECT_FALSE(query2->IsPending());
@@ -343,7 +360,7 @@
               GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
       .WillOnce(SetArgPointee<2>(0))
       .RetiresOnSaturation();
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->ProcessPendingQueries(false);
   EXPECT_TRUE(query3->IsPending());
   EXPECT_EQ(0, sync3->process_count);
   EXPECT_EQ(0u, sync3->result);
@@ -358,69 +375,13 @@
   EXPECT_CALL(*gl_, GetQueryObjectuiv(kService3Id, GL_QUERY_RESULT_EXT, _))
       .WillOnce(SetArgPointee<2>(kResult3))
       .RetiresOnSaturation();
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->ProcessPendingQueries(false);
   EXPECT_FALSE(query3->IsPending());
   EXPECT_EQ(kSubmitCount3, sync3->process_count);
   EXPECT_EQ(kResult3, sync3->result);
   EXPECT_FALSE(manager_->HavePendingQueries());
 }
 
-TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryId) {
-  const GLuint kClient1Id = 1;
-  const GLuint kService1Id = 11;
-  const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;
-  const base::subtle::Atomic32 kSubmitCount = 123;
-  const GLuint kResult = 1;
-
-  // Create Query.
-  scoped_refptr<QueryManager::Query> query(
-      CreateQuery(kTarget, kClient1Id,
-                  kInvalidSharedMemoryId, kSharedMemoryOffset, kService1Id));
-  ASSERT_TRUE(query.get() != NULL);
-
-  // Queue it
-  QueueQuery(query.get(), kService1Id, kSubmitCount);
-
-  // Process with return available.
-  // Expect 2 GL commands.
-  EXPECT_CALL(*gl_,
-              GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
-      .WillOnce(SetArgPointee<2>(1))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _))
-      .WillOnce(SetArgPointee<2>(kResult))
-      .RetiresOnSaturation();
-  EXPECT_FALSE(manager_->ProcessPendingQueries(false));
-}
-
-TEST_F(QueryManagerTest, ProcessPendingBadSharedMemoryOffset) {
-  const GLuint kClient1Id = 1;
-  const GLuint kService1Id = 11;
-  const GLenum kTarget = GL_ANY_SAMPLES_PASSED_EXT;
-  const base::subtle::Atomic32 kSubmitCount = 123;
-  const GLuint kResult = 1;
-
-  // Create Query.
-  scoped_refptr<QueryManager::Query> query(
-      CreateQuery(kTarget, kClient1Id, shared_memory_id_,
-                  kInvalidSharedMemoryOffset, kService1Id));
-  ASSERT_TRUE(query.get() != NULL);
-
-  // Queue it
-  QueueQuery(query.get(), kService1Id, kSubmitCount);
-
-  // Process with return available.
-  // Expect 2 GL commands.
-  EXPECT_CALL(*gl_,
-              GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
-      .WillOnce(SetArgPointee<2>(1))
-      .RetiresOnSaturation();
-  EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _))
-      .WillOnce(SetArgPointee<2>(kResult))
-      .RetiresOnSaturation();
-  EXPECT_FALSE(manager_->ProcessPendingQueries(false));
-}
-
 TEST_F(QueryManagerTest, ExitWithPendingQuery) {
   const GLuint kClient1Id = 1;
   const GLuint kService1Id = 11;
@@ -453,11 +414,9 @@
   std::unique_ptr<QueryManager> manager(
       new QueryManager(decoder_.get(), feature_info.get()));
 
-  EXPECT_CALL(*gl_, GenQueries(1, _))
-      .WillOnce(SetArgPointee<1>(kService1Id))
-      .RetiresOnSaturation();
-  QueryManager::Query* query = manager->CreateQuery(
-      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset);
+  QueryManager::Query* query =
+      CreateQueryOnManager(manager.get(), kTarget, kClient1Id,
+                           shared_memory_id_, kSharedMemoryOffset, kService1Id);
   ASSERT_TRUE(query != NULL);
 
   EXPECT_CALL(*gl_, BeginQuery(GL_ANY_SAMPLES_PASSED_EXT, kService1Id))
@@ -466,8 +425,8 @@
   EXPECT_CALL(*gl_, EndQuery(GL_ANY_SAMPLES_PASSED_EXT))
       .Times(1)
       .RetiresOnSaturation();
-  EXPECT_TRUE(manager->BeginQuery(query));
-  EXPECT_TRUE(manager->EndQuery(query, kSubmitCount));
+  manager->BeginQuery(query);
+  manager->EndQuery(query, kSubmitCount);
   manager->Destroy(false);
 }
 
@@ -487,11 +446,9 @@
   std::unique_ptr<QueryManager> manager(
       new QueryManager(decoder_.get(), feature_info.get()));
 
-  EXPECT_CALL(*gl_, GenQueries(1, _))
-      .WillOnce(SetArgPointee<1>(kService1Id))
-      .RetiresOnSaturation();
-  QueryManager::Query* query = manager->CreateQuery(
-      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset);
+  QueryManager::Query* query =
+      CreateQueryOnManager(manager.get(), kTarget, kClient1Id,
+                           shared_memory_id_, kSharedMemoryOffset, kService1Id);
   ASSERT_TRUE(query != NULL);
 
   EXPECT_CALL(*gl_, BeginQuery(GL_SAMPLES_PASSED_ARB, kService1Id))
@@ -500,8 +457,8 @@
   EXPECT_CALL(*gl_, EndQuery(GL_SAMPLES_PASSED_ARB))
       .Times(1)
       .RetiresOnSaturation();
-  EXPECT_TRUE(manager->BeginQuery(query));
-  EXPECT_TRUE(manager->EndQuery(query, kSubmitCount));
+  manager->BeginQuery(query);
+  manager->EndQuery(query, kSubmitCount);
   manager->Destroy(false);
 }
 
@@ -520,17 +477,15 @@
   std::unique_ptr<QueryManager> manager(
       new QueryManager(decoder_.get(), feature_info.get()));
 
-  EXPECT_CALL(*gl_, GenQueries(1, _))
-      .WillOnce(SetArgPointee<1>(kService1Id))
-      .RetiresOnSaturation();
-  QueryManager::Query* query = manager->CreateQuery(
-      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset);
+  QueryManager::Query* query =
+      CreateQueryOnManager(manager.get(), kTarget, kClient1Id,
+                           shared_memory_id_, kSharedMemoryOffset, kService1Id);
   ASSERT_TRUE(query != NULL);
 
   EXPECT_CALL(*gl_, BeginQuery(GL_SAMPLES_PASSED_ARB, kService1Id))
       .Times(1)
       .RetiresOnSaturation();
-  EXPECT_TRUE(manager->BeginQuery(query));
+  manager->BeginQuery(query);
 
   // Pause and Resume the manager.
   EXPECT_CALL(*gl_, EndQuery(GL_SAMPLES_PASSED_ARB))
@@ -549,7 +504,7 @@
   EXPECT_CALL(*gl_, EndQuery(GL_SAMPLES_PASSED_ARB))
       .Times(1)
       .RetiresOnSaturation();
-  EXPECT_TRUE(manager->EndQuery(query, kSubmitCount));
+  manager->EndQuery(query, kSubmitCount);
 
   EXPECT_CALL(*gl_,
               GetQueryObjectuiv(kService2Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
@@ -561,7 +516,7 @@
   EXPECT_CALL(*gl_, GetQueryObjectuiv(kService2Id, GL_QUERY_RESULT_EXT, _))
       .WillOnce(SetArgPointee<2>(1u))
       .RetiresOnSaturation();
-  EXPECT_TRUE(manager->ProcessPendingQueries(false));
+  manager->ProcessPendingQueries(false);
   EXPECT_TRUE(query->IsFinished());
 
   QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
@@ -578,8 +533,8 @@
   EXPECT_CALL(*gl_, EndQuery(GL_SAMPLES_PASSED_ARB))
       .Times(1)
       .RetiresOnSaturation();
-  EXPECT_TRUE(manager->BeginQuery(query));
-  EXPECT_TRUE(manager->EndQuery(query, kSubmitCount + 1));
+  manager->BeginQuery(query);
+  manager->EndQuery(query, kSubmitCount + 1);
 
   EXPECT_CALL(*gl_,
               GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_AVAILABLE_EXT, _))
@@ -588,7 +543,7 @@
   EXPECT_CALL(*gl_, GetQueryObjectuiv(kService1Id, GL_QUERY_RESULT_EXT, _))
       .WillOnce(SetArgPointee<2>(0u))
       .RetiresOnSaturation();
-  EXPECT_TRUE(manager->ProcessPendingQueries(false));
+  manager->ProcessPendingQueries(false);
   EXPECT_TRUE(query->IsFinished());
 
   EXPECT_EQ(0u, sync->result);
@@ -606,18 +561,18 @@
   decoder_->GetGLContext()->CreateGPUTimingClient()->SetCpuTimeForTesting(
       base::Bind(&gl::GPUTimingFake::GetFakeCPUTime));
 
-  QueryManager::Query* query = manager_->CreateQuery(
-      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset);
+  QueryManager::Query* query = CreateQuery(
+      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, 0);
   ASSERT_TRUE(query != NULL);
 
   fake_timing_queries.ExpectGPUTimerQuery(*gl_, true);
   fake_timing_queries.SetCurrentGLTime(
       200 * base::Time::kNanosecondsPerMicrosecond);
-  EXPECT_TRUE(manager_->BeginQuery(query));
+  manager_->BeginQuery(query);
   fake_timing_queries.SetCurrentGLTime(
       300 * base::Time::kNanosecondsPerMicrosecond);
-  EXPECT_TRUE(manager_->EndQuery(query, kSubmitCount));
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->EndQuery(query, kSubmitCount);
+  manager_->ProcessPendingQueries(false);
 
   EXPECT_TRUE(query->IsFinished());
 
@@ -638,14 +593,14 @@
   decoder_->GetGLContext()->CreateGPUTimingClient()->SetCpuTimeForTesting(
       base::Bind(&gl::GPUTimingFake::GetFakeCPUTime));
 
-  QueryManager::Query* query = manager_->CreateQuery(
-      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset);
+  QueryManager::Query* query = CreateQuery(
+      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, 0);
   ASSERT_TRUE(query != NULL);
 
   fake_timing_queries.ExpectGPUTimerQuery(*gl_, true);
   fake_timing_queries.SetCurrentGLTime(
       200 * base::Time::kNanosecondsPerMicrosecond);
-  EXPECT_TRUE(manager_->BeginQuery(query));
+  manager_->BeginQuery(query);
 
   // Pause and Resume here.
   fake_timing_queries.SetCurrentGLTime(
@@ -658,9 +613,9 @@
 
   fake_timing_queries.SetCurrentGLTime(
       500 * base::Time::kNanosecondsPerMicrosecond);
-  EXPECT_TRUE(manager_->EndQuery(query, kSubmitCount));
+  manager_->EndQuery(query, kSubmitCount);
 
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->ProcessPendingQueries(false);
   EXPECT_TRUE(query->IsFinished());
 
   QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
@@ -672,11 +627,11 @@
   // Make sure next query works properly.
   fake_timing_queries.SetCurrentGLTime(
       600 * base::Time::kNanosecondsPerMicrosecond);
-  EXPECT_TRUE(manager_->BeginQuery(query));
+  manager_->BeginQuery(query);
   fake_timing_queries.SetCurrentGLTime(
       700 * base::Time::kNanosecondsPerMicrosecond);
-  EXPECT_TRUE(manager_->EndQuery(query, kSubmitCount + 1));
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->EndQuery(query, kSubmitCount + 1);
+  manager_->ProcessPendingQueries(false);
 
   EXPECT_TRUE(query->IsFinished());
 
@@ -706,27 +661,27 @@
   const GLenum kTarget = GL_TIME_ELAPSED_EXT;
   const base::subtle::Atomic32 kSubmitCount = 123;
 
-  QueryManager::Query* query = manager_->CreateQuery(
-      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset);
+  QueryManager::Query* query = CreateQuery(
+      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, 0);
   ASSERT_TRUE(query != NULL);
 
   // Disjoint happening before the query should not trigger a disjoint event.
   fake_timing_queries.SetDisjoint();
 
   fake_timing_queries.ExpectGPUTimerQuery(*gl_, true);
-  EXPECT_TRUE(manager_->BeginQuery(query));
-  EXPECT_TRUE(manager_->EndQuery(query, kSubmitCount));
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->BeginQuery(query);
+  manager_->EndQuery(query, kSubmitCount);
+  manager_->ProcessPendingQueries(false);
 
   EXPECT_TRUE(query->IsFinished());
   EXPECT_EQ(current_disjoint_value, disjoint_sync->GetDisjointCount());
 
   // Disjoint happening during query should trigger disjoint event.
   fake_timing_queries.ExpectGPUTimerQuery(*gl_, true);
-  EXPECT_TRUE(manager_->BeginQuery(query));
+  manager_->BeginQuery(query);
   fake_timing_queries.SetDisjoint();
-  EXPECT_TRUE(manager_->EndQuery(query, kSubmitCount));
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->EndQuery(query, kSubmitCount);
+  manager_->ProcessPendingQueries(false);
 
   EXPECT_TRUE(query->IsFinished());
   EXPECT_NE(current_disjoint_value, disjoint_sync->GetDisjointCount());
@@ -743,16 +698,16 @@
   decoder_->GetGLContext()->CreateGPUTimingClient()->SetCpuTimeForTesting(
       base::Bind(&gl::GPUTimingFake::GetFakeCPUTime));
 
-  QueryManager::Query* query = manager_->CreateQuery(
-      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset);
+  QueryManager::Query* query = CreateQuery(
+      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, 0);
   ASSERT_TRUE(query != NULL);
 
   const uint64_t expected_result =
       100u * base::Time::kNanosecondsPerMicrosecond;
   fake_timing_queries.SetCurrentGLTime(expected_result);
   fake_timing_queries.ExpectGPUTimeStampQuery(*gl_, false);
-  EXPECT_TRUE(manager_->QueryCounter(query, kSubmitCount));
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->QueryCounter(query, kSubmitCount);
+  manager_->ProcessPendingQueries(false);
 
   QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
       shared_memory_id_, kSharedMemoryOffset, sizeof(*sync));
@@ -770,19 +725,19 @@
   decoder_->GetGLContext()->CreateGPUTimingClient()->SetCpuTimeForTesting(
       base::Bind(&gl::GPUTimingFake::GetFakeCPUTime));
 
-  QueryManager::Query* query = manager_->CreateQuery(
-      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset);
+  QueryManager::Query* query = CreateQuery(
+      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, 0);
   ASSERT_TRUE(query != NULL);
 
   const uint64_t expected_result =
       100u * base::Time::kNanosecondsPerMicrosecond;
   fake_timing_queries.SetCurrentGLTime(expected_result);
   fake_timing_queries.ExpectGPUTimeStampQuery(*gl_, false);
-  EXPECT_TRUE(manager_->QueryCounter(query, kSubmitCount));
+  manager_->QueryCounter(query, kSubmitCount);
   EXPECT_TRUE(query->IsPending());
   fake_timing_queries.ExpectGPUTimeStampQuery(*gl_, false);
-  EXPECT_TRUE(manager_->QueryCounter(query, kSubmitCount));
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->QueryCounter(query, kSubmitCount);
+  manager_->ProcessPendingQueries(false);
 
   QuerySync* sync = decoder_->GetSharedMemoryAs<QuerySync*>(
       shared_memory_id_, kSharedMemoryOffset, sizeof(*sync));
@@ -810,25 +765,25 @@
   const GLenum kTarget = GL_TIMESTAMP_EXT;
   const base::subtle::Atomic32 kSubmitCount = 123;
 
-  QueryManager::Query* query = manager_->CreateQuery(
-      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset);
+  QueryManager::Query* query = CreateQuery(
+      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, 0);
   ASSERT_TRUE(query != NULL);
 
   // Disjoint happening before the query should not trigger a disjoint event.
   fake_timing_queries.SetDisjoint();
 
   fake_timing_queries.ExpectGPUTimeStampQuery(*gl_, false);
-  EXPECT_TRUE(manager_->QueryCounter(query, kSubmitCount));
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->QueryCounter(query, kSubmitCount);
+  manager_->ProcessPendingQueries(false);
 
   EXPECT_TRUE(query->IsFinished());
   EXPECT_EQ(current_disjoint_value, disjoint_sync->GetDisjointCount());
 
   // Disjoint happening during query should trigger disjoint event.
   fake_timing_queries.ExpectGPUTimeStampQuery(*gl_, false);
-  EXPECT_TRUE(manager_->QueryCounter(query, kSubmitCount));
+  manager_->QueryCounter(query, kSubmitCount);
   fake_timing_queries.SetDisjoint();
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->ProcessPendingQueries(false);
 
   EXPECT_TRUE(query->IsFinished());
   EXPECT_NE(current_disjoint_value, disjoint_sync->GetDisjointCount());
@@ -860,13 +815,13 @@
   const GLenum kTarget = GL_TIMESTAMP_EXT;
   const base::subtle::Atomic32 kSubmitCount = 123;
 
-  QueryManager::Query* query = manager_->CreateQuery(
-      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset);
+  QueryManager::Query* query = CreateQuery(
+      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset, 0);
   ASSERT_TRUE(query != NULL);
 
   fake_timing_queries.ExpectGPUTimeStampQuery(*gl_, false);
-  EXPECT_TRUE(manager_->QueryCounter(query, kSubmitCount));
-  EXPECT_TRUE(manager_->ProcessPendingQueries(false));
+  manager_->QueryCounter(query, kSubmitCount);
+  manager_->ProcessPendingQueries(false);
 
   EXPECT_EQ(current_disjoint_value, disjoint_sync->GetDisjointCount());
   fake_timing_queries.SetDisjoint();
@@ -887,8 +842,9 @@
   std::unique_ptr<QueryManager> manager(
       new QueryManager(decoder_.get(), feature_info.get()));
 
-  QueryManager::Query* query = manager->CreateQuery(
-      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset);
+  QueryManager::Query* query =
+      CreateQueryOnManager(manager.get(), kTarget, kClient1Id,
+                           shared_memory_id_, kSharedMemoryOffset, 0);
   ASSERT_TRUE(query != NULL);
 
   // Setup shared memory like client would.
@@ -897,7 +853,7 @@
   ASSERT_TRUE(sync != NULL);
   sync->Reset();
 
-  EXPECT_TRUE(manager->BeginQuery(query));
+  manager->BeginQuery(query);
 
   MockErrorState mock_error_state;
   EXPECT_CALL(*decoder_.get(), GetErrorState())
@@ -906,7 +862,7 @@
       .WillOnce(Return(GL_INVALID_ENUM))
       .RetiresOnSaturation();
 
-  EXPECT_TRUE(manager->EndQuery(query, kSubmitCount));
+  manager->EndQuery(query, kSubmitCount);
   EXPECT_FALSE(query->IsPending());
 
   EXPECT_EQ(static_cast<GLuint>(GL_INVALID_ENUM), sync->result);
@@ -928,11 +884,9 @@
   std::unique_ptr<QueryManager> manager(
       new QueryManager(decoder_.get(), feature_info.get()));
 
-  EXPECT_CALL(*gl_, GenQueries(1, _))
-      .WillOnce(SetArgPointee<1>(kService1Id))
-      .RetiresOnSaturation();
-  QueryManager::Query* query = manager->CreateQuery(
-      kTarget, kClient1Id, shared_memory_id_, kSharedMemoryOffset);
+  QueryManager::Query* query =
+      CreateQueryOnManager(manager.get(), kTarget, kClient1Id,
+                           shared_memory_id_, kSharedMemoryOffset, kService1Id);
   ASSERT_TRUE(query != NULL);
 
   EXPECT_CALL(*gl_, BeginQuery(GL_SAMPLES_PASSED_ARB, kService1Id))
@@ -941,8 +895,8 @@
   EXPECT_CALL(*gl_, EndQuery(GL_SAMPLES_PASSED_ARB))
       .Times(1)
       .RetiresOnSaturation();
-  EXPECT_TRUE(manager->BeginQuery(query));
-  EXPECT_TRUE(manager->EndQuery(query, kSubmitCount));
+  manager->BeginQuery(query);
+  manager->EndQuery(query, kSubmitCount);
   manager->Destroy(false);
 }
 
diff --git a/gpu/config/gpu_driver_bug_list.json b/gpu/config/gpu_driver_bug_list.json
index 9576577..d194f9ff1 100644
--- a/gpu/config/gpu_driver_bug_list.json
+++ b/gpu/config/gpu_driver_bug_list.json
@@ -1,6 +1,6 @@
 {
   "name": "gpu driver bug list",
-  "version": "10.17",
+  "version": "10.18",
   "entries": [
     {
       "id": 1,
@@ -2564,6 +2564,23 @@
       "features": [
         "rely_on_implicit_sync_for_swap_buffers"
       ]
+    },
+    {
+      "id": 236,
+      "description": "glClearColor does not always work on Intel 6xxx Mac drivers",
+      "cr_bugs": [710443],
+      "os": {
+        "type": "macosx",
+        "version": {
+          "op": "<",
+          "value": "10.12.6"
+        }
+      },
+      "vendor_id": "0x8086",
+      "device_id": ["0x1626", "0x162B", "0x1622"],
+      "features": [
+        "clear_to_zero_or_one_broken"
+      ]
     }
   ],
   "comment": [
diff --git a/gpu/config/gpu_driver_bug_workaround_type.h b/gpu/config/gpu_driver_bug_workaround_type.h
index ffe1402..67c224a 100644
--- a/gpu/config/gpu_driver_bug_workaround_type.h
+++ b/gpu/config/gpu_driver_bug_workaround_type.h
@@ -29,6 +29,8 @@
          broken_egl_image_ref_counting)                      \
   GPU_OP(CLEAR_ALPHA_IN_READPIXELS,                          \
          clear_alpha_in_readpixels)                          \
+  GPU_OP(CLEAR_TO_ZERO_OR_ONE_BROKEN,                        \
+         clear_to_zero_or_one_broken)                        \
   GPU_OP(CLEAR_UNIFORMS_BEFORE_FIRST_PROGRAM_USE,            \
          clear_uniforms_before_first_program_use)            \
   GPU_OP(COUNT_ALL_IN_VARYINGS_PACKING,                      \
diff --git a/gpu/ipc/service/direct_composition_surface_win.cc b/gpu/ipc/service/direct_composition_surface_win.cc
index 066edf0..706fa86e 100644
--- a/gpu/ipc/service/direct_composition_surface_win.cc
+++ b/gpu/ipc/service/direct_composition_surface_win.cc
@@ -474,8 +474,8 @@
 
 void DCLayerTree::SwapChainPresenter::PresentToSwapChain(
     const ui::DCRendererLayerParams& params) {
-  gl::GLImageDXGIBase* image_dxgi =
-      gl::GLImageDXGIBase::FromGLImage(params.image[0].get());
+  gl::GLImageDXGI* image_dxgi =
+      gl::GLImageDXGI::FromGLImage(params.image[0].get());
   gl::GLImageMemory* y_image_memory = nullptr;
   gl::GLImageMemory* uv_image_memory = nullptr;
   if (params.image.size() >= 2) {
@@ -557,13 +557,9 @@
 
   base::win::ScopedComPtr<ID3D11Texture2D> input_texture;
   UINT input_level;
-  base::win::ScopedComPtr<IDXGIKeyedMutex> keyed_mutex;
   if (image_dxgi) {
     input_texture = image_dxgi->texture();
     input_level = (UINT)image_dxgi->level();
-    if (!input_texture)
-      return;
-    input_texture.CopyTo(keyed_mutex.GetAddressOf());
     staging_texture_.Reset();
   } else {
     DCHECK(y_image_memory);
@@ -628,19 +624,6 @@
   }
 
   {
-    if (keyed_mutex) {
-      // The producer may still be using this texture for a short period of
-      // time, so wait long enough to hopefully avoid glitches. For example,
-      // all levels of the texture share the same keyed mutex, so if the
-      // hardware decoder acquired the mutex to decode into a different array
-      // level then it still may block here temporarily.
-      const int kMaxSyncTimeMs = 1000;
-      HRESULT hr = keyed_mutex->AcquireSync(0, kMaxSyncTimeMs);
-      if (FAILED(hr)) {
-        DLOG(ERROR) << "Error acquiring keyed mutex: " << std::hex << hr;
-        return;
-      }
-    }
     D3D11_VIDEO_PROCESSOR_INPUT_VIEW_DESC in_desc = {};
     in_desc.ViewDimension = D3D11_VPIV_DIMENSION_TEXTURE2D;
     in_desc.Texture2D.ArraySlice = input_level;
@@ -669,10 +652,6 @@
     hr = video_context_->VideoProcessorBlt(video_processor_.Get(),
                                            out_view_.Get(), 0, 1, &stream);
     CHECK(SUCCEEDED(hr));
-    if (keyed_mutex) {
-      HRESULT hr = keyed_mutex->ReleaseSync(0);
-      DCHECK(SUCCEEDED(hr));
-    }
   }
 
   if (first_present) {
diff --git a/gpu/ipc/service/direct_composition_surface_win_unittest.cc b/gpu/ipc/service/direct_composition_surface_win_unittest.cc
index 264c44b..62d9cb5 100644
--- a/gpu/ipc/service/direct_composition_surface_win_unittest.cc
+++ b/gpu/ipc/service/direct_composition_surface_win_unittest.cc
@@ -111,8 +111,7 @@
 
 base::win::ScopedComPtr<ID3D11Texture2D> CreateNV12Texture(
     const base::win::ScopedComPtr<ID3D11Device>& d3d11_device,
-    const gfx::Size& size,
-    bool shared) {
+    const gfx::Size& size) {
   D3D11_TEXTURE2D_DESC desc = {};
   desc.Width = size.width();
   desc.Height = size.height();
@@ -122,10 +121,6 @@
   desc.Usage = D3D11_USAGE_DEFAULT;
   desc.SampleDesc.Count = 1;
   desc.BindFlags = 0;
-  if (shared) {
-    desc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX |
-                     D3D11_RESOURCE_MISC_SHARED_NTHANDLE;
-  }
 
   std::vector<char> image_data(size.width() * size.height() * 3 / 2);
   // Y, U, and V should all be Oxff. Output color should be pink.
@@ -322,7 +317,7 @@
 
   gfx::Size texture_size(50, 50);
   base::win::ScopedComPtr<ID3D11Texture2D> texture =
-      CreateNV12Texture(d3d11_device, texture_size, false);
+      CreateNV12Texture(d3d11_device, texture_size);
 
   scoped_refptr<gl::GLImageDXGI> image_dxgi(
       new gl::GLImageDXGI(texture_size, nullptr));
@@ -498,7 +493,7 @@
 
   gfx::Size texture_size(50, 50);
   base::win::ScopedComPtr<ID3D11Texture2D> texture =
-      CreateNV12Texture(d3d11_device, texture_size, false);
+      CreateNV12Texture(d3d11_device, texture_size);
 
   scoped_refptr<gl::GLImageDXGI> image_dxgi(
       new gl::GLImageDXGI(texture_size, nullptr));
@@ -587,55 +582,5 @@
   context = nullptr;
   DestroySurface(std::move(surface_));
 }
-
-TEST_F(DirectCompositionPixelTest, VideoHandleSwapchain) {
-  if (!CheckIfDCSupported())
-    return;
-  InitializeSurface();
-  surface_->SetEnableDCLayers(true);
-  gfx::Size window_size(100, 100);
-
-  scoped_refptr<gl::GLContext> context = gl::init::CreateGLContext(
-      nullptr, surface_.get(), gl::GLContextAttribs());
-  EXPECT_TRUE(surface_->Resize(window_size, 1.0, true));
-
-  base::win::ScopedComPtr<ID3D11Device> d3d11_device =
-      gl::QueryD3D11DeviceObjectFromANGLE();
-
-  gfx::Size texture_size(50, 50);
-  base::win::ScopedComPtr<ID3D11Texture2D> texture =
-      CreateNV12Texture(d3d11_device, texture_size, true);
-  base::win::ScopedComPtr<IDXGIResource1> resource;
-  texture.CopyTo(resource.GetAddressOf());
-  HANDLE handle;
-  resource->CreateSharedHandle(nullptr, DXGI_SHARED_RESOURCE_READ, nullptr,
-                               &handle);
-
-  scoped_refptr<gl::GLImageDXGIHandle> image_dxgi(new gl::GLImageDXGIHandle(
-      texture_size, base::win::ScopedHandle(handle), 0));
-  ASSERT_TRUE(image_dxgi->Initialize());
-
-  ui::DCRendererLayerParams params(
-      false, gfx::Rect(), 1, gfx::Transform(),
-      std::vector<scoped_refptr<gl::GLImage>>{image_dxgi},
-      gfx::RectF(gfx::Rect(texture_size)), gfx::Rect(window_size), 0, 0, 1.0,
-      0);
-  surface_->ScheduleDCLayer(params);
-
-  EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface_->SwapBuffers());
-
-  Sleep(1000);
-
-  SkColor expected_color = SkColorSetRGB(0xff, 0xb7, 0xff);
-  SkColor actual_color =
-      ReadBackWindowPixel(window_.hwnd(), gfx::Point(75, 75));
-  EXPECT_TRUE(AreColorsSimilar(expected_color, actual_color))
-      << std::hex << "Expected " << expected_color << " Actual "
-      << actual_color;
-
-  context = nullptr;
-  DestroySurface(std::move(surface_));
-}
-
 }  // namespace
 }  // namespace gpu
diff --git a/ios/BUILD.gn b/ios/BUILD.gn
index d091b5b..43b032d 100644
--- a/ios/BUILD.gn
+++ b/ios/BUILD.gn
@@ -34,8 +34,6 @@
   if (is_cronet_build) {
     deps = [
       "//components/cronet/ios:cronet_package",
-      "//ios/crnet:crnet_framework",
-      "//ios/crnet/test:crnet_test",
     ]
   } else {
     deps = [
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd
index d8437f1..55bab02e 100644
--- a/ios/chrome/app/strings/ios_strings.grd
+++ b/ios/chrome/app/strings/ios_strings.grd
@@ -1245,6 +1245,12 @@
       <message name="IDS_IOS_CONFIRM_PASSWORD_DELETION" desc="Label of a confirmation dialogue button which allows the user to confirm deletion of a stored password. [Length: one line] [iOS only]">
         Delete Saved Password
       </message>
+      <message name="IDS_IOS_SETTINGS_PASSWORDS_SAVED_HEADING" desc="The title for a list of username/site/password items. These items are already saved by the browser and can be deleted/edited. [Length: one line] [iOS only]">
+      Saved Passwords
+      </message>
+      <message name="IDS_IOS_SETTINGS_PASSWORDS_EXCEPTIONS_HEADING" desc="The title for a list of sites where passwords will not be saved. These items are already saved by the browser and can only be deleted. [Length: one line] [iOS only]">
+      Never Saved
+      </message>
       <message name="IDS_IOS_SIGNED_IN_ACCOUNTS_VIEW_OK_BUTTON" desc="The title of the OK button of the Signed In Accounts view [iOS only] [20em]">
         OK, Got It
       </message>
diff --git a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
index a61413a..56a91d4 100644
--- a/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
+++ b/ios/chrome/browser/content_suggestions/content_suggestions_coordinator.mm
@@ -31,6 +31,7 @@
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
+#import "ios/chrome/browser/ui/commands/new_tab_command.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/cells/content_suggestions_most_visited_item.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h"
@@ -337,8 +338,7 @@
                    didTriggerAction:(OverscrollAction)action {
   switch (action) {
     case OverscrollAction::NEW_TAB: {
-      base::scoped_nsobject<GenericChromeCommand> command(
-          [[GenericChromeCommand alloc] initWithTag:IDC_NEW_TAB]);
+      NewTabCommand* command = [[NewTabCommand alloc] initWithIncognito:NO];
       [self.suggestionsViewController chromeExecuteCommand:command];
     } break;
     case OverscrollAction::CLOSE_TAB: {
diff --git a/ios/chrome/browser/ui/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view_controller.mm
index ee0cd0a8..fbd26ee 100644
--- a/ios/chrome/browser/ui/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view_controller.mm
@@ -101,6 +101,7 @@
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
+#import "ios/chrome/browser/ui/commands/new_tab_command.h"
 #import "ios/chrome/browser/ui/commands/open_url_command.h"
 #import "ios/chrome/browser/ui/commands/reading_list_add_command.h"
 #import "ios/chrome/browser/ui/commands/show_mail_composer_command.h"
@@ -2025,21 +2026,17 @@
 #pragma mark - Tap handling
 
 - (void)setLastTapPoint:(id)sender {
-  CGPoint center;
-  UIView* parentView = nil;
-  if ([sender isKindOfClass:[UIView class]]) {
-    center = [sender center];
-    parentView = [sender superview];
-  }
-  if ([sender isKindOfClass:[ToolsMenuViewItem class]]) {
-    parentView = [[sender tableViewCell] superview];
-    center = [[sender tableViewCell] center];
-  }
+  NewTabCommand* command = base::mac::ObjCCast<NewTabCommand>(sender);
+  if (!command)
+    return;
 
-  if (parentView) {
-    _lastTapPoint = [parentView convertPoint:center toView:self.view];
-    _lastTapTime = CACurrentMediaTime();
+  if (CGPointEqualToPoint(command.originPoint, CGPointZero)) {
+    _lastTapPoint = CGPointZero;
+  } else {
+    _lastTapPoint =
+        [self.view.window convertPoint:command.originPoint toView:self.view];
   }
+  _lastTapTime = CACurrentMediaTime();
 }
 
 - (CGPoint)lastTapPoint {
@@ -3526,7 +3523,6 @@
   // Dismiss the soft keyboard (if open).
   Tab* tab = [_model currentTab];
   [tab.webController dismissKeyboard];
-
   web::NavigationItemList backwardItems =
       [tab navigationManager]->GetBackwardItems();
   [_toolbarController showTabHistoryPopupInView:[self view]
@@ -3673,7 +3669,7 @@
   if (entry->type != sessions::TabRestoreService::TAB)
     return;
 
-  [self chromeExecuteCommand:[GenericChromeCommand commandWithTag:IDC_NEW_TAB]];
+  [self chromeExecuteCommand:[[NewTabCommand alloc] initWithIncognito:NO]];
   TabRestoreServiceDelegateImplIOS* const delegate =
       TabRestoreServiceDelegateImplIOSFactory::GetForBrowserState(
           _browserState);
diff --git a/ios/chrome/browser/ui/commands/BUILD.gn b/ios/chrome/browser/ui/commands/BUILD.gn
index bd70f35..364e34fb 100644
--- a/ios/chrome/browser/ui/commands/BUILD.gn
+++ b/ios/chrome/browser/ui/commands/BUILD.gn
@@ -14,6 +14,8 @@
     "generic_chrome_command.h",
     "generic_chrome_command.mm",
     "ios_command_ids.h",
+    "new_tab_command.h",
+    "new_tab_command.mm",
     "open_url_command.h",
     "open_url_command.mm",
     "reading_list_add_command.h",
diff --git a/ios/chrome/browser/ui/commands/new_tab_command.h b/ios/chrome/browser/ui/commands/new_tab_command.h
new file mode 100644
index 0000000..1b24cdc
--- /dev/null
+++ b/ios/chrome/browser/ui/commands/new_tab_command.h
@@ -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.
+
+#ifndef IOS_CHROME_BROWSER_UI_COMMANDS_NEW_TAB_COMMAND_H_
+#define IOS_CHROME_BROWSER_UI_COMMANDS_NEW_TAB_COMMAND_H_
+
+#import <UIKit/UIKit.h>
+
+#import "ios/chrome/browser/ui/commands/generic_chrome_command.h"
+
+// Command sent to open a new tab, optionally including a point (in UIWindow
+// coordinates).
+@interface NewTabCommand : GenericChromeCommand
+
+- (instancetype)initWithIncognito:(BOOL)incognito
+                      originPoint:(CGPoint)originPoint
+    NS_DESIGNATED_INITIALIZER;
+
+// Create a NewTabCommand with an OriginPoint of CGPointZero.
+- (instancetype)initWithIncognito:(BOOL)incognito;
+
+// Mark inherited initializer as unavailable to prevent calling it by mistake.
+- (instancetype)initWithTag:(NSInteger)tag NS_UNAVAILABLE;
+
+@property(nonatomic, readonly) BOOL incognito;
+
+@property(nonatomic, readonly) CGPoint originPoint;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_COMMANDS_NEW_TAB_COMMAND_H_
diff --git a/ios/chrome/browser/ui/commands/new_tab_command.mm b/ios/chrome/browser/ui/commands/new_tab_command.mm
new file mode 100644
index 0000000..5a0951c
--- /dev/null
+++ b/ios/chrome/browser/ui/commands/new_tab_command.mm
@@ -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.
+
+#import "ios/chrome/browser/ui/commands/new_tab_command.h"
+
+#import "ios/chrome/browser/ui/commands/ios_command_ids.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@implementation NewTabCommand
+
+@synthesize incognito = _incognito;
+@synthesize originPoint = _originPoint;
+
+- (instancetype)initWithIncognito:(BOOL)incognito
+                      originPoint:(CGPoint)originPoint {
+  int tag = incognito ? IDC_NEW_INCOGNITO_TAB : IDC_NEW_TAB;
+  if ((self = [super initWithTag:tag])) {
+    _incognito = incognito;
+    _originPoint = originPoint;
+  }
+  return self;
+}
+
+- (instancetype)initWithIncognito:(BOOL)incognito {
+  return [self initWithIncognito:incognito originPoint:CGPointZero];
+}
+
+@end
diff --git a/ios/chrome/browser/ui/key_commands_provider.mm b/ios/chrome/browser/ui/key_commands_provider.mm
index 023d3c7cb..8a67be2 100644
--- a/ios/chrome/browser/ui/key_commands_provider.mm
+++ b/ios/chrome/browser/ui/key_commands_provider.mm
@@ -8,6 +8,7 @@
 #include "components/strings/grit/components_strings.h"
 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
+#import "ios/chrome/browser/ui/commands/new_tab_command.h"
 #import "ios/chrome/browser/ui/keyboard/UIKeyCommand+Chrome.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
 #include "ios/chrome/grit/ios_strings.h"
@@ -64,6 +65,19 @@
     };
   }
 
+  // New tab blocks.
+  void (^newTab)() = ^{
+    [weakConsumer
+        chromeExecuteCommand:[[NewTabCommand alloc]
+                                 initWithIncognito:[weakConsumer
+                                                       isOffTheRecord]]];
+  };
+
+  void (^newIncognitoTab)() = ^{
+    [weakConsumer
+        chromeExecuteCommand:[[NewTabCommand alloc] initWithIncognito:YES]];
+  };
+
   const int browseLeftDescriptionID = useRTLLayout
                                           ? IDS_IOS_KEYBOARD_HISTORY_FORWARD
                                           : IDS_IOS_KEYBOARD_HISTORY_BACK;
@@ -81,21 +95,13 @@
                            modifierFlags:UIKeyModifierCommand
                                    title:l10n_util::GetNSStringWithFixup(
                                              IDS_IOS_TOOLS_MENU_NEW_TAB)
-                                  action:^{
-                                    if ([weakConsumer isOffTheRecord]) {
-                                      execute(IDC_NEW_INCOGNITO_TAB);
-                                    } else {
-                                      execute(IDC_NEW_TAB);
-                                    }
-                                  }],
+                                  action:newTab],
     [UIKeyCommand
         cr_keyCommandWithInput:@"n"
                  modifierFlags:UIKeyModifierCommand | UIKeyModifierShift
                          title:l10n_util::GetNSStringWithFixup(
                                    IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB)
-                        action:^{
-                          execute(IDC_NEW_INCOGNITO_TAB);
-                        }],
+                        action:newIncognitoTab],
     [UIKeyCommand
         cr_keyCommandWithInput:@"t"
                  modifierFlags:UIKeyModifierCommand | UIKeyModifierShift
@@ -169,16 +175,12 @@
                                modifierFlags:UIKeyModifierCommand
                                        title:l10n_util::GetNSStringWithFixup(
                                                  browseLeftDescriptionID)
-                                      action:^{
-                                        browseLeft();
-                                      }],
+                                      action:browseLeft],
         [UIKeyCommand cr_keyCommandWithInput:UIKeyInputRightArrow
                                modifierFlags:UIKeyModifierCommand
                                        title:l10n_util::GetNSStringWithFixup(
                                                  browseRightDescriptionID)
-                                      action:^{
-                                        browseRight();
-                                      }],
+                                      action:browseRight],
       ]];
     }
 
@@ -213,13 +215,7 @@
     [UIKeyCommand cr_keyCommandWithInput:@"n"
                            modifierFlags:UIKeyModifierCommand
                                    title:nil
-                                  action:^{
-                                    if ([weakConsumer isOffTheRecord]) {
-                                      execute(IDC_NEW_INCOGNITO_TAB);
-                                    } else {
-                                      execute(IDC_NEW_TAB);
-                                    }
-                                  }],
+                                  action:newTab],
     [UIKeyCommand cr_keyCommandWithInput:@","
                            modifierFlags:UIKeyModifierCommand
                                    title:nil
@@ -235,15 +231,11 @@
       [UIKeyCommand cr_keyCommandWithInput:@"["
                              modifierFlags:UIKeyModifierCommand
                                      title:nil
-                                    action:^{
-                                      browseLeft();
-                                    }],
+                                    action:browseLeft],
       [UIKeyCommand cr_keyCommandWithInput:@"]"
                              modifierFlags:UIKeyModifierCommand
                                      title:nil
-                                    action:^{
-                                      browseRight();
-                                    }],
+                                    action:browseRight],
       [UIKeyCommand cr_keyCommandWithInput:@"."
                              modifierFlags:UIKeyModifierCommand
                                      title:nil
diff --git a/ios/chrome/browser/ui/ntp/google_landing_view_controller.mm b/ios/chrome/browser/ui/ntp/google_landing_view_controller.mm
index 5149dac..ed05e34 100644
--- a/ios/chrome/browser/ui/ntp/google_landing_view_controller.mm
+++ b/ios/chrome/browser/ui/ntp/google_landing_view_controller.mm
@@ -14,6 +14,7 @@
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
+#import "ios/chrome/browser/ui/commands/new_tab_command.h"
 #import "ios/chrome/browser/ui/content_suggestions/content_suggestions_collection_utils.h"
 #import "ios/chrome/browser/ui/context_menu/context_menu_coordinator.h"
 #import "ios/chrome/browser/ui/ntp/google_landing_data_source.h"
@@ -1221,8 +1222,7 @@
                    didTriggerAction:(OverscrollAction)action {
   switch (action) {
     case OverscrollAction::NEW_TAB: {
-      GenericChromeCommand* command =
-          [[GenericChromeCommand alloc] initWithTag:IDC_NEW_TAB];
+      NewTabCommand* command = [[NewTabCommand alloc] initWithIncognito:NO];
       [[self view] chromeExecuteCommand:command];
     } break;
     case OverscrollAction::CLOSE_TAB:
diff --git a/ios/chrome/browser/ui/payments/payment_request_manager.mm b/ios/chrome/browser/ui/payments/payment_request_manager.mm
index 1662d9c..eed9dcc 100644
--- a/ios/chrome/browser/ui/payments/payment_request_manager.mm
+++ b/ios/chrome/browser/ui/payments/payment_request_manager.mm
@@ -575,7 +575,8 @@
     DLOG(ERROR) << "JS message parameter 'payment_details' is missing";
     return NO;
   }
-  if (!paymentDetails.FromDictionaryValue(*paymentDetailsData)) {
+  if (!paymentDetails.FromDictionaryValue(*paymentDetailsData,
+                                          /*requires_total=*/false)) {
     DLOG(ERROR) << "JS message parameter 'payment_details' is invalid";
     return NO;
   }
diff --git a/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm b/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm
index d2c9c7a..04badcf 100644
--- a/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/password_details_collection_view_controller.mm
@@ -320,14 +320,16 @@
   UIPasteboard* generalPasteboard = [UIPasteboard generalPasteboard];
   generalPasteboard.string = _site;
   [self showCopyResultToast:l10n_util::GetNSString(
-                                IDS_IOS_SETTINGS_SITE_WAS_COPIED_MESSAGE)];
+                                IDS_IOS_SETTINGS_SITE_WAS_COPIED_MESSAGE)
+                 forSuccess:YES];
 }
 
 - (void)copyUsername {
   UIPasteboard* generalPasteboard = [UIPasteboard generalPasteboard];
   generalPasteboard.string = _username;
   [self showCopyResultToast:l10n_util::GetNSString(
-                                IDS_IOS_SETTINGS_USERNAME_WAS_COPIED_MESSAGE)];
+                                IDS_IOS_SETTINGS_USERNAME_WAS_COPIED_MESSAGE)
+                 forSuccess:YES];
 }
 
 - (NSString*)showHideButtonText {
@@ -400,10 +402,9 @@
   if (_plainTextPasswordShown) {
     UIPasteboard* generalPasteboard = [UIPasteboard generalPasteboard];
     generalPasteboard.string = _password;
-    TriggerHapticFeedbackForNotification(UINotificationFeedbackTypeSuccess);
-    [self
-        showCopyResultToast:l10n_util::GetNSString(
-                                IDS_IOS_SETTINGS_PASSWORD_WAS_COPIED_MESSAGE)];
+    [self showCopyResultToast:l10n_util::GetNSString(
+                                  IDS_IOS_SETTINGS_PASSWORD_WAS_COPIED_MESSAGE)
+                   forSuccess:YES];
     UMA_HISTOGRAM_ENUMERATION(
         "PasswordManager.AccessPasswordInSettings",
         password_manager::metrics_util::ACCESS_PASSWORD_COPIED,
@@ -421,19 +422,19 @@
       if (success) {
         UIPasteboard* generalPasteboard = [UIPasteboard generalPasteboard];
         generalPasteboard.string = strongSelf->_password;
-        TriggerHapticFeedbackForNotification(UINotificationFeedbackTypeSuccess);
         [strongSelf showCopyResultToast:
                         l10n_util::GetNSString(
-                            IDS_IOS_SETTINGS_PASSWORD_WAS_COPIED_MESSAGE)];
+                            IDS_IOS_SETTINGS_PASSWORD_WAS_COPIED_MESSAGE)
+                             forSuccess:YES];
         UMA_HISTOGRAM_ENUMERATION(
             "PasswordManager.AccessPasswordInSettings",
             password_manager::metrics_util::ACCESS_PASSWORD_COPIED,
             password_manager::metrics_util::ACCESS_PASSWORD_COUNT);
       } else {
-        TriggerHapticFeedbackForNotification(UINotificationFeedbackTypeError);
         [strongSelf showCopyResultToast:
                         l10n_util::GetNSString(
-                            IDS_IOS_SETTINGS_PASSWORD_WAS_NOT_COPIED_MESSAGE)];
+                            IDS_IOS_SETTINGS_PASSWORD_WAS_NOT_COPIED_MESSAGE)
+                             forSuccess:NO];
       }
     };
     [_weakReauthenticationModule
@@ -443,9 +444,14 @@
   }
 }
 
-- (void)showCopyResultToast:(NSString*)message {
+// Show a MD snack bar and provide haptic feedback. The haptic feedback is
+// either for success or for error, depending on |success|.
+- (void)showCopyResultToast:(NSString*)message forSuccess:(BOOL)success {
   // TODO(crbug.com/159166): Route this through some delegate API to be able
   // to mock it in the unittest, and avoid having an EGTest just for that?
+  TriggerHapticFeedbackForNotification(success
+                                           ? UINotificationFeedbackTypeSuccess
+                                           : UINotificationFeedbackTypeError);
   MDCSnackbarMessage* copyPasswordResultMessage =
       [MDCSnackbarMessage messageWithText:message];
   copyPasswordResultMessage.category = @"PasswordsSnackbarCategory";
diff --git a/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm b/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm
index 64c58c9..6a32f16 100644
--- a/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm
+++ b/ios/chrome/browser/ui/settings/passwords_settings_egtest.mm
@@ -570,7 +570,7 @@
   // of the list of passwords.
   [[EarlGrey selectElementWithMatcher:
                  grey_allOf(grey_accessibilityLabel(l10n_util::GetNSString(
-                                IDS_PASSWORD_MANAGER_SHOW_PASSWORDS_TAB_TITLE)),
+                                IDS_IOS_SETTINGS_PASSWORDS_SAVED_HEADING)),
                             grey_accessibilityTrait(UIAccessibilityTraitHeader),
                             nullptr)] assertWithMatcher:grey_notNil()];
 
diff --git a/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm b/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm
index d34eb1c..b38d68c 100644
--- a/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm
+++ b/ios/chrome/browser/ui/settings/save_passwords_collection_view_controller.mm
@@ -22,7 +22,6 @@
 #include "components/password_manager/core/common/password_manager_pref_names.h"
 #include "components/prefs/pref_member.h"
 #include "components/prefs/pref_service.h"
-#include "components/strings/grit/components_strings.h"
 #include "components/url_formatter/url_formatter.h"
 #include "ios/chrome/browser/application_context.h"
 #include "ios/chrome/browser/browser_state/chrome_browser_state.h"
@@ -209,7 +208,7 @@
       CollectionViewTextItem* headerItem =
           [[CollectionViewTextItem alloc] initWithType:ItemTypeHeader];
       headerItem.text =
-          l10n_util::GetNSString(IDS_PASSWORD_MANAGER_SHOW_PASSWORDS_TAB_TITLE);
+          l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORDS_SAVED_HEADING);
       headerItem.textColor = [[MDCPalette greyPalette] tint500];
       [model setHeader:headerItem
           forSectionWithIdentifier:SectionIdentifierSavedPasswords];
@@ -223,7 +222,7 @@
       CollectionViewTextItem* headerItem =
           [[CollectionViewTextItem alloc] initWithType:ItemTypeHeader];
       headerItem.text =
-          l10n_util::GetNSString(IDS_PASSWORD_MANAGER_EXCEPTIONS_TAB_TITLE);
+          l10n_util::GetNSString(IDS_IOS_SETTINGS_PASSWORDS_EXCEPTIONS_HEADING);
       headerItem.textColor = [[MDCPalette greyPalette] tint500];
       [model setHeader:headerItem
           forSectionWithIdentifier:SectionIdentifierBlacklist];
diff --git a/ios/chrome/browser/ui/settings/settings_egtest.mm b/ios/chrome/browser/ui/settings/settings_egtest.mm
index cad68a0..2f0384a 100644
--- a/ios/chrome/browser/ui/settings/settings_egtest.mm
+++ b/ios/chrome/browser/ui/settings/settings_egtest.mm
@@ -402,9 +402,9 @@
 
   id<GREYMatcher> visibilityMatcher =
       saved ? grey_sufficientlyVisible() : grey_notVisible();
-  [[EarlGrey selectElementWithMatcher:
-                 grey_text(l10n_util::GetNSString(
-                     IDS_PASSWORD_MANAGER_SHOW_PASSWORDS_TAB_TITLE))]
+  [[EarlGrey
+      selectElementWithMatcher:grey_text(l10n_util::GetNSString(
+                                   IDS_IOS_SETTINGS_PASSWORDS_SAVED_HEADING))]
       assertWithMatcher:visibilityMatcher];
 
   // Close the Settings.
diff --git a/ios/chrome/browser/ui/stack_view/stack_view_controller.mm b/ios/chrome/browser/ui/stack_view/stack_view_controller.mm
index 4d57005..a263b028 100644
--- a/ios/chrome/browser/ui/stack_view/stack_view_controller.mm
+++ b/ios/chrome/browser/ui/stack_view/stack_view_controller.mm
@@ -32,6 +32,7 @@
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
+#import "ios/chrome/browser/ui/commands/new_tab_command.h"
 #import "ios/chrome/browser/ui/keyboard/UIKeyCommand+Chrome.h"
 #import "ios/chrome/browser/ui/ntp/new_tab_page_toolbar_controller.h"
 #import "ios/chrome/browser/ui/reversed_animation.h"
@@ -2016,20 +2017,15 @@
 }
 
 - (void)setLastTapPoint:(id)sender {
-  UIView* parentView = nil;
-  CGPoint center;
-  if ([sender isKindOfClass:[UIView class]]) {
-    center = [sender center];
-    parentView = [sender superview];
-  }
-  if ([sender isKindOfClass:[ToolsMenuViewItem class]]) {
-    parentView = [[sender tableViewCell] superview];
-    center = [[sender tableViewCell] center];
-  }
+  NewTabCommand* command = base::mac::ObjCCast<NewTabCommand>(sender);
+  if (!command)
+    return;
 
-  if (parentView) {
-    CGPoint viewCoordinate = [parentView convertPoint:center toView:self.view];
-    _lastTapPoint = viewCoordinate;
+  if (CGPointEqualToPoint(command.originPoint, CGPointZero)) {
+    _lastTapPoint = CGPointZero;
+  } else {
+    _lastTapPoint =
+        [self.view.window convertPoint:command.originPoint toView:self.view];
   }
 }
 
@@ -3484,9 +3480,18 @@
 - (NSArray*)keyCommands {
   __weak StackViewController* weakSelf = self;
 
-  // Block to execute a command from the |tag|.
-  void (^execute)(NSInteger) = ^(NSInteger tag) {
-    [weakSelf chromeExecuteCommand:[GenericChromeCommand commandWithTag:tag]];
+  // New tab blocks.
+  void (^newTab)() = ^{
+    [weakSelf
+        chromeExecuteCommand:[[NewTabCommand alloc]
+                                 initWithIncognito:[weakSelf
+                                                       isCurrentSetIncognito]]];
+
+  };
+
+  void (^newIncognitoTab)() = ^{
+    [weakSelf
+        chromeExecuteCommand:[[NewTabCommand alloc] initWithIncognito:YES]];
   };
 
   return @[
@@ -3494,29 +3499,17 @@
                            modifierFlags:UIKeyModifierCommand
                                    title:l10n_util::GetNSStringWithFixup(
                                              IDS_IOS_TOOLS_MENU_NEW_TAB)
-                                  action:^{
-                                    if ([weakSelf isCurrentSetIncognito])
-                                      execute(IDC_NEW_INCOGNITO_TAB);
-                                    else
-                                      execute(IDC_NEW_TAB);
-                                  }],
+                                  action:newTab],
     [UIKeyCommand
         cr_keyCommandWithInput:@"n"
                  modifierFlags:UIKeyModifierCommand | UIKeyModifierShift
                          title:l10n_util::GetNSStringWithFixup(
                                    IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB)
-                        action:^{
-                          execute(IDC_NEW_INCOGNITO_TAB);
-                        }],
+                        action:newIncognitoTab],
     [UIKeyCommand cr_keyCommandWithInput:@"n"
                            modifierFlags:UIKeyModifierCommand
                                    title:nil
-                                  action:^{
-                                    if ([weakSelf isCurrentSetIncognito])
-                                      execute(IDC_NEW_INCOGNITO_TAB);
-                                    else
-                                      execute(IDC_NEW_TAB);
-                                  }],
+                                  action:newTab],
   ];
 }
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm
index bfbaedb..9b958c7 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_controller.mm
@@ -24,6 +24,7 @@
 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h"
 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
+#import "ios/chrome/browser/ui/commands/new_tab_command.h"
 #import "ios/chrome/browser/ui/keyboard/UIKeyCommand+Chrome.h"
 #include "ios/chrome/browser/ui/ntp/recent_tabs/synced_sessions.h"
 #import "ios/chrome/browser/ui/ntp/recent_tabs/views/signed_in_sync_off_view.h"
@@ -927,7 +928,8 @@
   if (entry->type != sessions::TabRestoreService::TAB)
     return;
 
-  [self chromeExecuteCommand:[GenericChromeCommand commandWithTag:IDC_NEW_TAB]];
+  NewTabCommand* command = [[NewTabCommand alloc] initWithIncognito:NO];
+  [self chromeExecuteCommand:command];
   TabRestoreServiceDelegateImplIOS* const delegate =
       TabRestoreServiceDelegateImplIOSFactory::GetForBrowserState(
           _browserState);
@@ -1113,10 +1115,8 @@
 - (void)openNewTabInPanelAtIndex:(NSInteger)panelIndex {
   CHECK(panelIndex >= 0);
   DCHECK([self isPanelIndexForLocalSession:panelIndex]);
-  const NSInteger tag = (panelIndex == kLocalTabsOnTheRecordPanelIndex)
-                            ? IDC_NEW_TAB
-                            : IDC_NEW_INCOGNITO_TAB;
-  if (tag == IDC_NEW_INCOGNITO_TAB) {
+  BOOL incognito = !(panelIndex == kLocalTabsOnTheRecordPanelIndex);
+  if (incognito) {
     base::RecordAction(
         base::UserMetricsAction("MobileTabSwitcherCreateIncognitoTab"));
   } else {
@@ -1124,8 +1124,7 @@
         base::UserMetricsAction("MobileTabSwitcherCreateNonIncognitoTab"));
   }
   // Create and execute command to create the tab.
-  GenericChromeCommand* command =
-      [[GenericChromeCommand alloc] initWithTag:tag];
+  NewTabCommand* command = [[NewTabCommand alloc] initWithIncognito:incognito];
   [self chromeExecuteCommand:command];
 }
 
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_overlay_view.mm b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_overlay_view.mm
index ab2d712..cda03e6e 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_overlay_view.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_overlay_view.mm
@@ -4,6 +4,7 @@
 
 #import "ios/chrome/browser/ui/tab_switcher/tab_switcher_panel_overlay_view.h"
 
+#include "base/mac/foundation_util.h"
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
 #include "components/signin/core/browser/signin_metrics.h"
@@ -15,6 +16,7 @@
 #import "ios/chrome/browser/ui/colors/MDCPalette+CrAdditions.h"
 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
+#import "ios/chrome/browser/ui/commands/new_tab_command.h"
 #import "ios/chrome/browser/ui/commands/show_signin_command.h"
 #import "ios/chrome/browser/ui/material_components/activity_indicator.h"
 #import "ios/chrome/browser/ui/sync/sync_util.h"
@@ -410,15 +412,13 @@
       shouldShowTextButton = NO;
       break;
     case TabSwitcherPanelOverlayType::OVERLAY_PANEL_USER_NO_OPEN_TABS:
-      tag = IDC_NEW_TAB;
-      selector = @selector(rootViewControllerChromeCommand:);
+      selector = @selector(sendNewTabCommand:);
       _recordedMetricString = "MobileTabSwitcherCreateNonIncognitoTab";
       shouldShowTextButton = NO;
       shouldShowFloatingButton = YES;
       break;
     case TabSwitcherPanelOverlayType::OVERLAY_PANEL_USER_NO_INCOGNITO_TABS:
-      tag = IDC_NEW_INCOGNITO_TAB;
-      selector = @selector(rootViewControllerChromeCommand:);
+      selector = @selector(sendNewIncognitoTabCommand:);
       _recordedMetricString = "MobileTabSwitcherCreateIncognitoTab";
       shouldShowTextButton = NO;
       shouldShowFloatingButton = YES;
@@ -456,7 +456,19 @@
                                  _browserState)];
 }
 
-- (void)rootViewControllerChromeCommand:(id)command {
+- (void)sendNewTabCommand:(id)sender {
+  UIView* view = base::mac::ObjCCast<UIView>(sender);
+  CGPoint center = [view.superview convertPoint:view.center toView:view.window];
+  NewTabCommand* command =
+      [[NewTabCommand alloc] initWithIncognito:NO originPoint:center];
+  [self chromeExecuteCommand:command];
+}
+
+- (void)sendNewIncognitoTabCommand:(id)sender {
+  UIView* view = base::mac::ObjCCast<UIView>(sender);
+  CGPoint center = [view.superview convertPoint:view.center toView:view.window];
+  NewTabCommand* command =
+      [[NewTabCommand alloc] initWithIncognito:YES originPoint:center];
   [self chromeExecuteCommand:command];
 }
 
diff --git a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
index 7261aae..ae9c0b6 100644
--- a/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
+++ b/ios/chrome/browser/ui/tabs/tab_strip_controller.mm
@@ -22,6 +22,7 @@
 #import "ios/chrome/browser/tabs/tab_model_observer.h"
 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
+#import "ios/chrome/browser/ui/commands/new_tab_command.h"
 #import "ios/chrome/browser/ui/fullscreen_controller.h"
 #include "ios/chrome/browser/ui/rtl_geometry.h"
 #include "ios/chrome/browser/ui/tab_switcher/tab_switcher_tab_strip_placeholder_view.h"
@@ -185,6 +186,9 @@
   // The model index of the placeholder gap, if one exists.  This value is used
   // as the new model index of the dragged tab when it is dropped.
   NSUInteger _placeholderGapModelIndex;
+
+  // YES if this tab strip is representing an incognito TabModel.
+  BOOL _isIncognito;
 }
 
 @property(nonatomic, readonly, retain) TabStripView* tabStripView;
@@ -358,10 +362,7 @@
     CGRect buttonNewTabFrame = tabStripFrame;
     buttonNewTabFrame.size.width = kNewTabButtonWidth;
     _buttonNewTab = [[UIButton alloc] initWithFrame:buttonNewTabFrame];
-    BOOL isBrowserStateIncognito =
-        tabModel && tabModel.browserState->IsOffTheRecord();
-    _buttonNewTab.tag =
-        isBrowserStateIncognito ? IDC_NEW_INCOGNITO_TAB : IDC_NEW_TAB;
+    _isIncognito = tabModel && tabModel.browserState->IsOffTheRecord();
     // TODO(crbug.com/600829): Rewrite layout code and convert these masks to
     // to trailing and leading margins rather than right and bottom.
     _buttonNewTab.autoresizingMask = (UIViewAutoresizingFlexibleRightMargin |
@@ -391,13 +392,13 @@
     _buttonNewTab.imageEdgeInsets = imageInsets;
     SetA11yLabelAndUiAutomationName(
         _buttonNewTab,
-        isBrowserStateIncognito ? IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB
-                                : IDS_IOS_TOOLS_MENU_NEW_TAB,
-        isBrowserStateIncognito ? @"New Incognito Tab" : @"New Tab");
+        _isIncognito ? IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB
+                     : IDS_IOS_TOOLS_MENU_NEW_TAB,
+        _isIncognito ? @"New Incognito Tab" : @"New Tab");
     // Use a nil target to send |-chromeExecuteCommand:| down the responder
     // chain.
-    [_buttonNewTab addTarget:nil
-                      action:@selector(chromeExecuteCommand:)
+    [_buttonNewTab addTarget:self
+                      action:@selector(sendNewTabCommand)
             forControlEvents:UIControlEventTouchUpInside];
     [_buttonNewTab addTarget:self
                       action:@selector(recordUserMetrics:)
@@ -579,6 +580,14 @@
                  << base::SysNSStringToUTF8([sender description]);
 }
 
+- (void)sendNewTabCommand {
+  CGPoint center = [_buttonNewTab.superview convertPoint:_buttonNewTab.center
+                                                  toView:_buttonNewTab.window];
+  NewTabCommand* command =
+      [[NewTabCommand alloc] initWithIncognito:_isIncognito originPoint:center];
+  [_view chromeExecuteCommand:command];
+}
+
 - (void)tabTapped:(id)sender {
   DCHECK([sender isKindOfClass:[TabView class]]);
 
diff --git a/ios/chrome/browser/ui/toolbar/new_tab_button.h b/ios/chrome/browser/ui/toolbar/new_tab_button.h
index 7e26ea2..bbad6227 100644
--- a/ios/chrome/browser/ui/toolbar/new_tab_button.h
+++ b/ios/chrome/browser/ui/toolbar/new_tab_button.h
@@ -9,8 +9,8 @@
 
 // UIButton subclass used for the New Tab button in the phone switcher toolbar
 // and the tablet no-tabs toolbar. A NewTabButton has a custom background rect
-// and by default will call it's own (derived) -chromeExecuteCommand method
-// on |TouchUpInside|, and has a tag of |IDC_NEW_TAB|. Instances can add further
+// and by default will call send a NewTabCommand via its (derived)
+// -chromeExecuteCommand method on |TouchUpInside|. Instances can add further
 // targets.
 @interface NewTabButton : UIButton
 // Whether the button opens incognito tabs or not; setting this property changes
diff --git a/ios/chrome/browser/ui/toolbar/new_tab_button.mm b/ios/chrome/browser/ui/toolbar/new_tab_button.mm
index ab29bca..e3178d9 100644
--- a/ios/chrome/browser/ui/toolbar/new_tab_button.mm
+++ b/ios/chrome/browser/ui/toolbar/new_tab_button.mm
@@ -6,7 +6,7 @@
 
 #include "base/logging.h"
 #import "ios/chrome/browser/ui/commands/UIKit+ChromeExecuteCommand.h"
-#include "ios/chrome/browser/ui/commands/ios_command_ids.h"
+#import "ios/chrome/browser/ui/commands/new_tab_command.h"
 #import "ios/chrome/browser/ui/image_util.h"
 #import "ios/chrome/browser/ui/rtl_geometry.h"
 #import "ios/chrome/browser/ui/uikit_ui_util.h"
@@ -37,7 +37,7 @@
     self.incognito = NO;
 
     [self addTarget:self
-                  action:@selector(chromeExecuteCommand:)
+                  action:@selector(sendNewTabCommand)
         forControlEvents:UIControlEventTouchUpInside];
 
     [self
@@ -50,7 +50,6 @@
 }
 
 - (void)setIncognito:(BOOL)incognito {
-  self.tag = incognito ? IDC_NEW_INCOGNITO_TAB : IDC_NEW_TAB;
   NSString* normalImageName = @"toolbar_dark_newtab";
   NSString* activeImageName = @"toolbar_dark_newtab_active";
   if (incognito) {
@@ -86,4 +85,12 @@
   }
 }
 
+- (void)sendNewTabCommand {
+  CGPoint center = [self.superview convertPoint:self.center toView:self.window];
+  NewTabCommand* command =
+      [[NewTabCommand alloc] initWithIncognito:self.isIncognito
+                                   originPoint:center];
+  [self chromeExecuteCommand:command];
+}
+
 @end
diff --git a/ios/chrome/browser/ui/tools_menu/BUILD.gn b/ios/chrome/browser/ui/tools_menu/BUILD.gn
index 15dde6b1..d920bb2 100644
--- a/ios/chrome/browser/ui/tools_menu/BUILD.gn
+++ b/ios/chrome/browser/ui/tools_menu/BUILD.gn
@@ -5,6 +5,8 @@
 source_set("tools_menu") {
   configs += [ "//build/config/compiler:enable_arc" ]
   sources = [
+    "new_tab_menu_view_item.h",
+    "new_tab_menu_view_item.mm",
     "reading_list_menu_view_item.h",
     "reading_list_menu_view_item.mm",
     "tools_menu_constants.h",
diff --git a/ios/chrome/browser/ui/tools_menu/new_tab_menu_view_item.h b/ios/chrome/browser/ui/tools_menu/new_tab_menu_view_item.h
new file mode 100644
index 0000000..36540e3
--- /dev/null
+++ b/ios/chrome/browser/ui/tools_menu/new_tab_menu_view_item.h
@@ -0,0 +1,20 @@
+// 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 IOS_CHROME_BROWSER_UI_TOOLS_MENU_NEW_TAB_MENU_VIEW_ITEM_H_
+#define IOS_CHROME_BROWSER_UI_TOOLS_MENU_NEW_TAB_MENU_VIEW_ITEM_H_
+
+#import <UIKit/UIKit.h>
+
+#import "ios/chrome/browser/ui/tools_menu/tools_menu_view_item.h"
+
+// Specialization of a ToolsMenuViewItem for opening a new tab.
+@interface NewTabMenuViewItem : ToolsMenuViewItem
+@end
+
+// Specialization of a ToolsMenuViewItem for opening a new incognito tab.
+@interface NewIncognitoTabMenuViewItem : NewTabMenuViewItem
+@end
+
+#endif  // IOS_CHROME_BROWSER_UI_TOOLS_MENU_NEW_TAB_MENU_VIEW_ITEM_H_
diff --git a/ios/chrome/browser/ui/tools_menu/new_tab_menu_view_item.mm b/ios/chrome/browser/ui/tools_menu/new_tab_menu_view_item.mm
new file mode 100644
index 0000000..f5d4157
--- /dev/null
+++ b/ios/chrome/browser/ui/tools_menu/new_tab_menu_view_item.mm
@@ -0,0 +1,38 @@
+// 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 "ios/chrome/browser/ui/tools_menu/new_tab_menu_view_item.h"
+
+#import "ios/chrome/browser/ui/commands/new_tab_command.h"
+
+#if !defined(__has_feature) || !__has_feature(objc_arc)
+#error "This file requires ARC support."
+#endif
+
+@interface NewTabMenuViewItem ()
+@property(nonatomic, readonly, getter=isIncognito) BOOL incognito;
+@end
+
+@implementation NewTabMenuViewItem
+
+- (BOOL)isIncognito {
+  return NO;
+}
+
+- (id)command {
+  UIView* view = self.tableViewCell;
+  CGPoint center = [view.superview convertPoint:view.center toView:view.window];
+  return [[NewTabCommand alloc] initWithIncognito:self.isIncognito
+                                      originPoint:center];
+}
+
+@end
+
+@implementation NewIncognitoTabMenuViewItem
+
+- (BOOL)isIncognito {
+  return YES;
+}
+
+@end
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_model.h b/ios/chrome/browser/ui/tools_menu/tools_menu_model.h
index dbadf55..44c3b02 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_model.h
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_model.h
@@ -10,7 +10,7 @@
 #import "ios/shared/chrome/browser/ui/tools_menu/tools_menu_configuration.h"
 
 // Total number of possible menu items.
-const int kToolsMenuNumberOfItems = 16;
+const int kToolsMenuNumberOfItems = 15;
 
 // Initialization table for all possible commands to initialize the
 // tools menu at run time. Data initialized into this structure is not mutable.
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_model.mm b/ios/chrome/browser/ui/tools_menu/tools_menu_model.mm
index 6ba82eb..f50ea51e 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_model.mm
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_model.mm
@@ -8,6 +8,7 @@
 #include "ios/chrome/browser/experimental_flags.h"
 #include "ios/chrome/browser/ui/commands/application_commands.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
+#import "ios/chrome/browser/ui/tools_menu/new_tab_menu_view_item.h"
 #import "ios/chrome/browser/ui/tools_menu/reading_list_menu_view_item.h"
 #include "ios/chrome/browser/ui/tools_menu/tools_menu_constants.h"
 #include "ios/chrome/browser/ui/ui_util.h"
@@ -25,20 +26,22 @@
 const NSInteger kVisibleIncognitoOnly = 1 << 0;
 const NSInteger kVisibleNotIncognitoOnly = 1 << 1;
 
-// Declare all the possible items.
+// Declare all the possible items. If adding or removing items update
+// kToolsMenuNumberOfItems with the new total count.
+
 // Formatting note: While these items are being refactored to use selectors
 // and the dispatcher instead of ChromeExecuteCommand (see crbug.com/738881),
 // the |command_id| and |selector| fields are grouped together, since one will
 // be either 0 or nullptr. Once the refactor is complete, all of the
 // |command_id| values will be 0, and that struct field will be removed.
-const MenuItemInfo itemInfoList[] = {
+const MenuItemInfo itemInfoList[kToolsMenuNumberOfItems] = {
     // clang-format off
   { IDS_IOS_TOOLS_MENU_NEW_TAB,           kToolsMenuNewTabId,
     IDC_NEW_TAB, nullptr,                 ToolbarTypeAll,
-    0,                                    nil },
+    0,                                    [NewTabMenuViewItem class] },
   { IDS_IOS_TOOLS_MENU_NEW_INCOGNITO_TAB, kToolsMenuNewIncognitoTabId,
     IDC_NEW_INCOGNITO_TAB, nullptr,       ToolbarTypeAll,
-    0,                                    nil },
+    0,                                    [NewIncognitoTabMenuViewItem class] },
   { IDS_IOS_TOOLS_MENU_CLOSE_ALL_TABS,    kToolsMenuCloseAllTabsId,
     IDC_CLOSE_ALL_TABS, nullptr,          ToolbarTypeSwitcheriPhone,
     kVisibleNotIncognitoOnly,             nil },
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.mm b/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.mm
index 4c15cf3..29697681 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.mm
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_view_controller.mm
@@ -568,7 +568,7 @@
         DCHECK([menuItem tag]);
         [_delegate commandWasSelected:[menuItem tag]];
         if ([menuItem tag] > 0) {
-          [self chromeExecuteCommand:menuItem];
+          [self chromeExecuteCommand:[menuItem command]];
         } else {
           DCHECK([menuItem selector]);
           DCHECK([self.dispatcher respondsToSelector:[menuItem selector]]);
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.h b/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.h
index 19cb2ad..d2bbe37 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.h
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.h
@@ -24,6 +24,11 @@
           accessibilityIdentifier:(NSString*)accessibilityIdentifier
                          selector:(SEL)selector
                           command:(int)commandID;
+
+// The object that should be sent via -chromeExecuteCommand: when this item is
+// tapped.
+- (id)command;
+
 @end
 
 @interface ToolsMenuViewCell : UICollectionViewCell
diff --git a/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.mm b/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.mm
index 250357bf..3bf9ef1 100644
--- a/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.mm
+++ b/ios/chrome/browser/ui/tools_menu/tools_menu_view_item.mm
@@ -62,6 +62,11 @@
   return menuItem;
 }
 
+- (id)command {
+  // Default is to return |self|.
+  return self;
+}
+
 @end
 
 @implementation ToolsMenuViewCell
diff --git a/ios/chrome/test/app/tab_test_util.mm b/ios/chrome/test/app/tab_test_util.mm
index 95dffda..10f549bf 100644
--- a/ios/chrome/test/app/tab_test_util.mm
+++ b/ios/chrome/test/app/tab_test_util.mm
@@ -17,6 +17,7 @@
 #import "ios/chrome/browser/ui/browser_view_controller.h"
 #import "ios/chrome/browser/ui/commands/generic_chrome_command.h"
 #include "ios/chrome/browser/ui/commands/ios_command_ids.h"
+#import "ios/chrome/browser/ui/commands/new_tab_command.h"
 #import "ios/chrome/browser/ui/tabs/tab_strip_controller_private.h"
 #import "ios/chrome/test/app/chrome_test_util.h"
 #import "ios/testing/wait_util.h"
@@ -51,7 +52,7 @@
 void OpenNewTab() {
   @autoreleasepool {  // Make sure that all internals are deallocated.
     GenericChromeCommand* command =
-        [[GenericChromeCommand alloc] initWithTag:IDC_NEW_TAB];
+        [[NewTabCommand alloc] initWithIncognito:NO];
     chrome_test_util::RunCommandWithActiveViewController(command);
   }
 }
@@ -59,7 +60,7 @@
 void OpenNewIncognitoTab() {
   @autoreleasepool {  // Make sure that all internals are deallocated.
     GenericChromeCommand* command =
-        [[GenericChromeCommand alloc] initWithTag:IDC_NEW_INCOGNITO_TAB];
+        [[NewTabCommand alloc] initWithIncognito:YES];
     chrome_test_util::RunCommandWithActiveViewController(command);
   }
 }
diff --git a/ios/clean/chrome/browser/ui/tools/tools_menu_model.h b/ios/clean/chrome/browser/ui/tools/tools_menu_model.h
index 23ebf056..ea5026b2 100644
--- a/ios/clean/chrome/browser/ui/tools/tools_menu_model.h
+++ b/ios/clean/chrome/browser/ui/tools/tools_menu_model.h
@@ -8,7 +8,7 @@
 #import <Foundation/Foundation.h>
 
 // Total number of possible menu items.
-const int kToolsMenuNumberOfItems = 16;
+const int kToolsMenuNumberOfItems = 15;
 
 // Struct for a single MenuModelItem.
 struct MenuModelItem {
diff --git a/ios/clean/chrome/browser/ui/tools/tools_menu_model.mm b/ios/clean/chrome/browser/ui/tools/tools_menu_model.mm
index 9f91434..24d3a337 100644
--- a/ios/clean/chrome/browser/ui/tools/tools_menu_model.mm
+++ b/ios/clean/chrome/browser/ui/tools/tools_menu_model.mm
@@ -10,8 +10,9 @@
 #import "ios/clean/chrome/browser/ui/commands/find_in_page_visibility_commands.h"
 #import "ios/clean/chrome/browser/ui/commands/settings_commands.h"
 
-// Declare all the possible items.
-const MenuModelItem itemsModelList[] = {
+// Declare all the possible items. If adding or removing items update
+// the value of kToolsMenuNumberOfItems with the new total count.
+const MenuModelItem itemsModelList[kToolsMenuNumberOfItems] = {
     // clang-format off
   { IDS_IOS_TOOLS_MENU_NEW_TAB,               kToolsMenuNewTabId,
     ToolbarTypeAll,                           ItemVisibleAlways,
diff --git a/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.h b/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.h
index 8ffbd8c8..0be926e7 100644
--- a/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.h
+++ b/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.h
@@ -24,9 +24,6 @@
 // object and may be nil.
 @property(nonatomic, weak) id<WebContentsConsumer> consumer;
 
-// Sets the active webState's webUsageEnabled to false.
-- (void)disconnect;
-
 @end
 
 #endif  // IOS_CLEAN_CHROME_BROWSER_UI_WEB_CONTENTS_WEB_CONTENTS_MEDIATOR_H_
diff --git a/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.mm b/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.mm
index cd4a28a0..cfd238a 100644
--- a/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.mm
+++ b/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator.mm
@@ -21,16 +21,9 @@
 @synthesize webState = _webState;
 @synthesize consumer = _consumer;
 
-#pragma mark - Public
-
-- (void)disconnect {
-  [self disableWebUsage:self.webState];
-}
-
 #pragma mark - Properties
 
 - (void)setWebState:(web::WebState*)webState {
-  [self disableWebUsage:_webState];
   _webState = webState;
   [self updateConsumerWithWebState:webState];
 }
@@ -44,17 +37,10 @@
 
 #pragma mark - Private
 
-- (void)disableWebUsage:(web::WebState*)webState {
-  if (webState) {
-    webState->SetWebUsageEnabled(false);
-  }
-}
-
-// Sets |webState| webUsageEnabled and updates the consumer's contentView.
+// Updates the consumer's contentView.
 - (void)updateConsumerWithWebState:(web::WebState*)webState {
   UIView* updatedView = nil;
   if (webState) {
-    webState->SetWebUsageEnabled(true);
     updatedView = webState->GetView();
     // PLACEHOLDER: This navigates the page since the omnibox is not yet
     // hooked up.
diff --git a/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator_unittest.mm b/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator_unittest.mm
index b1f6f7f7..f6ac06f8 100644
--- a/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator_unittest.mm
+++ b/ios/clean/chrome/browser/ui/web_contents/web_contents_mediator_unittest.mm
@@ -45,7 +45,6 @@
 
     mediator_ = [[WebContentsMediator alloc] init];
   }
-  ~WebContentsMediatorTest() override { [mediator_ disconnect]; }
 
   TabNavigationManager* navigation_manager() {
     return static_cast<TabNavigationManager*>(
@@ -63,25 +62,6 @@
   web::TestWebState new_test_web_state_;
 };
 
-// Tests that webUsage is disabled when mediator is disconnected.
-TEST_F(WebContentsMediatorTest, TestDisconnect) {
-  mediator_.webState = &test_web_state_;
-  EXPECT_TRUE(test_web_state_.IsWebUsageEnabled());
-  [mediator_ disconnect];
-  EXPECT_FALSE(test_web_state_.IsWebUsageEnabled());
-}
-
-// Tests that both the old and new active web states have WebUsageEnabled
-// updated.
-TEST_F(WebContentsMediatorTest, TestWebUsageEnabled) {
-  mediator_.webState = &test_web_state_;
-  test_web_state_.SetWebUsageEnabled(true);
-  new_test_web_state_.SetWebUsageEnabled(false);
-  mediator_.webState = &new_test_web_state_;
-  EXPECT_FALSE(test_web_state_.IsWebUsageEnabled());
-  EXPECT_TRUE(new_test_web_state_.IsWebUsageEnabled());
-}
-
 // Tests that a URL is loaded if the new active web state has zero navigation
 // items.
 TEST_F(WebContentsMediatorTest, TestURLHasLoaded) {
diff --git a/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm b/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm
index f6d323c..db3ac94a 100644
--- a/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm
+++ b/ios/clean/chrome/browser/ui/web_contents/web_coordinator.mm
@@ -59,7 +59,6 @@
 
 - (void)stop {
   [super stop];
-  [self.mediator disconnect];
 }
 
 - (void)childCoordinatorDidStart:(BrowserCoordinator*)childCoordinator {
diff --git a/ios/crnet/BUILD.gn b/ios/crnet/BUILD.gn
deleted file mode 100644
index fc89b0f..0000000
--- a/ios/crnet/BUILD.gn
+++ /dev/null
@@ -1,134 +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.
-
-import("//build/buildflag_header.gni")
-import("//build/config/ios/rules.gni")
-import("//build/config/mac/symbols.gni")
-import("//build/mac/tweak_info_plist.gni")
-import("//build/util/version.gni")
-import("//testing/test.gni")
-import("//url/features.gni")
-
-assert(!is_component_build, "CrNet requires static library build.")
-
-source_set("crnet_sources") {
-  configs += [ "//build/config/compiler:enable_arc" ]
-  deps = [
-    "//base",
-    "//components/metrics",
-    "//components/metrics/proto",
-    "//components/prefs",
-    "//ios/net",
-    "//ios/web:user_agent",
-    "//net",
-    "//url",
-    "//url:url_features",
-  ]
-
-  sources = [
-    "CrNet.h",
-    "CrNet.mm",
-    "crnet_environment.h",
-    "crnet_environment.mm",
-    "sdch_owner_pref_storage.cc",
-    "sdch_owner_pref_storage.h",
-  ]
-
-  if (!use_platform_icu_alternatives) {
-    deps += [ "//base:i18n" ]
-  }
-}
-
-# Tweak |info_plist| with current version and revision.
-tweak_info_plist("tweak_crnet_plist") {
-  info_plist = "Info.plist"
-}
-
-bundle_data("crnet_framework_resources") {
-  # This bundle contains "Accept-Languages" header values for known locales.
-  # TODO(mef): These strings should be auto-generated from chrome's .xtb
-  # files, not hardcoded.
-  sources = [
-    "Resources/Localization/am.lproj",
-    "Resources/Localization/ar.lproj",
-    "Resources/Localization/bg.lproj",
-    "Resources/Localization/bn.lproj",
-    "Resources/Localization/ca.lproj",
-    "Resources/Localization/cs.lproj",
-    "Resources/Localization/da.lproj",
-    "Resources/Localization/de.lproj",
-    "Resources/Localization/el.lproj",
-    "Resources/Localization/en-GB.lproj",
-    "Resources/Localization/en.lproj",
-    "Resources/Localization/es-419.lproj",
-    "Resources/Localization/es.lproj",
-    "Resources/Localization/fa.lproj",
-    "Resources/Localization/fi.lproj",
-    "Resources/Localization/fil.lproj",
-    "Resources/Localization/fr.lproj",
-    "Resources/Localization/gu.lproj",
-    "Resources/Localization/he.lproj",
-    "Resources/Localization/hi.lproj",
-    "Resources/Localization/hr.lproj",
-    "Resources/Localization/hu.lproj",
-    "Resources/Localization/id.lproj",
-    "Resources/Localization/it.lproj",
-    "Resources/Localization/ja.lproj",
-    "Resources/Localization/kn.lproj",
-    "Resources/Localization/ko.lproj",
-    "Resources/Localization/lt.lproj",
-    "Resources/Localization/lv.lproj",
-    "Resources/Localization/ml.lproj",
-    "Resources/Localization/mr.lproj",
-    "Resources/Localization/ms.lproj",
-    "Resources/Localization/nb.lproj",
-    "Resources/Localization/nl.lproj",
-    "Resources/Localization/pl.lproj",
-    "Resources/Localization/pt-BR.lproj",
-    "Resources/Localization/pt-PT.lproj",
-    "Resources/Localization/pt.lproj",
-    "Resources/Localization/ro.lproj",
-    "Resources/Localization/ru.lproj",
-    "Resources/Localization/sk.lproj",
-    "Resources/Localization/sl.lproj",
-    "Resources/Localization/sr.lproj",
-    "Resources/Localization/sv.lproj",
-    "Resources/Localization/sw.lproj",
-    "Resources/Localization/ta.lproj",
-    "Resources/Localization/te.lproj",
-    "Resources/Localization/th.lproj",
-    "Resources/Localization/tr.lproj",
-    "Resources/Localization/uk.lproj",
-    "Resources/Localization/vi.lproj",
-    "Resources/Localization/zh-Hans.lproj",
-    "Resources/Localization/zh-Hant.lproj",
-    "Resources/Localization/zh.lproj",
-  ]
-  outputs = [
-    "{{bundle_resources_dir}}/crnet_resources.bundle/{{source_file_part}}",
-  ]
-}
-
-ios_framework_bundle("crnet_framework") {
-  output_name = "CrNet"
-  info_plist_target = ":tweak_crnet_plist"
-
-  deps = [
-    ":crnet_framework_resources",
-    ":crnet_sources",
-    "//base",
-    "//net",
-  ]
-
-  libs = [ "UIKit.Framework" ]
-
-  public_headers = [ "CrNet.h" ]
-
-  sources = [
-    "CrNet.h",
-  ]
-
-  configs -= [ "//build/config/compiler:default_symbols" ]
-  configs += [ "//build/config/compiler:symbols" ]
-}
diff --git a/ios/crnet/CrNet.h b/ios/crnet/CrNet.h
deleted file mode 100644
index 4b1d4dc..0000000
--- a/ios/crnet/CrNet.h
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CRNET_CRNET_H_
-#define IOS_CRNET_CRNET_H_
-
-#import <Foundation/Foundation.h>
-
-// A block, that takes a request, and returns YES if the request should
-// be handled.
-typedef BOOL(^RequestFilterBlock)(NSURLRequest *request);
-
-
-// A callback, called when the clearCache message has completed. The |errorCode|
-// is a network stack error code indicating whether the clear request succeeded
-// or not. Even if the request failed, the cache may have been cleared anyway,
-// or it may not have; it is not useful to retry a failing cache-clear attempt.
-// The only real use of |errorCode| is for error reporting and statistics
-// gathering.
-typedef void(^ClearCacheCallback)(int errorCode);
-
-// Interface for installing CrNet.
-__attribute__((visibility("default")))
-@interface CrNet : NSObject
-
-// Sets whether HTTP/2 should be supported by CrNet. This method only has
-// any effect before |install| is called.
-+ (void)setHttp2Enabled:(BOOL)http2Enabled;
-
-// Sets whether QUIC should be supported by CrNet. This method only has any
-// effect before |install| is called.
-+ (void)setQuicEnabled:(BOOL)quicEnabled;
-
-// Sets whether SDCH should be supported by CrNet. This method only has any
-// effect before |install| is called. The |filename| argument is used to specify
-// which file should be used for SDCH persistence metadata. If |filename| is
-// nil, persistence is not enabled. The default is for SDCH to be disabled.
-+ (void)setSDCHEnabled:(BOOL)sdchEnabled
-         withPrefStore:(NSString *)filename;
-
-// Set partial UserAgent. This function is a deprecated shortcut for:
-//    [CrNet setUserAgent:userAgent partial:YES];
-// See the documentation for |setUserAgent| for details about the |userAgent|
-// argument.
-// This method only has any effect before |install| is called.
-+ (void)setPartialUserAgent:(NSString *)userAgent;
-
-// |userAgent| is expected to be the user agent value sent to remote.
-// If |partial| is set to YES, then actual user agent value is based on device
-// model, OS version, and |userAgent| argument. For example "Foo/3.0.0.0" is
-// sent as "Mozilla/5.0 (iPhone; CPU iPhone OS 9_3 like Mac OS X)
-// AppleWebKit/601.1 (KHTML, like Gecko) Foo/3.0.0.0 Mobile/15G31
-// Safari/601.1.46".
-// If partial is set to NO, then |userAgent| value is complete value sent to
-// the remote. For Example: "Foo/3.0.0.0" is sent as "Foo/3.0.0.0".
-//
-// This method only has any effect before |install| is called.
-+ (void)setUserAgent:(NSString*)userAgent partial:(bool)partial;
-
-// Set the block used to determine whether or not CrNet should handle the
-// request. If this is not set, CrNet will handle all requests.
-// Must not be called while requests are in progress. This method can be called
-// either before or after |install|.
-+ (void)setRequestFilterBlock:(RequestFilterBlock)block;
-
-// Installs CrNet. Once installed, CrNet intercepts and handles all
-// NSURLConnection and NSURLRequests issued by the app, including UIWebView page
-// loads. It is recommended to call this method on the application main thread.
-// If the method is called on any thread other than the main one, the method
-// will internally try to execute synchronously using the main GCD queue.
-// Please make sure that the main thread is not blocked by a job
-// that calls this method; otherwise, a deadlock can occur.
-+ (void)install;
-
-// Installs CrNet into an NSURLSession, passed in by the caller. Note that this
-// NSURLSession will share settings with the sharedSession, which the |install|
-// method installs CrNet into. This method must be called after |install|.
-+ (void)installIntoSessionConfiguration:(NSURLSessionConfiguration*)config;
-
-// Installs CrNet. This function is a deprecated shortcut for:
-//    [CrNet setPartialUserAgent:userAgent];
-//    [CrNet install];
-// See the documentation for |setPartialUserAgent| for details about the
-// |userAgent| argument.
-+ (void)installWithPartialUserAgent:(NSString *)userAgent
-    __attribute__((deprecated));
-
-// Installs CrNet. This function is a deprecated shortcut for:
-//    [CrNet setPartialUserAgent:userAgent];
-//    [CrNet install];
-// The |enableDataReductionProxy| argument is ignored since data reduction proxy
-// support is currently missing from CrNet. See |setPartialUserAgent| for
-// details about the |userAgent| argument.
-+ (void)installWithPartialUserAgent:(NSString *)userAgent
-           enableDataReductionProxy:(BOOL)enableDataReductionProxy
-           __attribute__((deprecated));
-
-// Installs CrNet. This function is a deprecated shortcut for:
-//    [CrNet setPartialUserAgent:userAgent];
-//    [CrNet setRequestFilterBlock:block];
-//    [CrNet install];
-// See |setPartialUserAgent| and |setRequestFilterBlock| for details about the
-// |userAgent| and |requestFilterBlock| arguments respectively.
-+ (void)installWithPartialUserAgent:(NSString *)userAgent
-             withRequestFilterBlock:(RequestFilterBlock)requestFilterBlock
-    __attribute__((deprecated));
-
-// Starts net-internals logging to a file named |fileName| in the application
-// temporary directory. |fileName| must not be empty. Log level is determined
-// by |logBytes| - if YES then LOG_ALL otherwise LOG_ALL_BUT_BYTES. If the file
-// exists it is truncated before starting. If actively logging the call is
-// ignored.
-+ (void)startNetLogToFile:(NSString *)fileName logBytes:(BOOL)logBytes;
-
-// Stop net-internals logging and flush file to disk. If a logging session is
-// not in progress this call is ignored.
-+ (void)stopNetLog;
-
-// Closes all current SPDY sessions. Do not do this unless you know what
-// you're doing.
-// TODO(alokm): This is a hack. Remove it later.
-+ (void)closeAllSpdySessions;
-
-// "Uninstalls" CrNet. This means that CrNet will stop intercepting requests.
-// However, it won't tear down all of the CrNet environment.
-+ (void)uninstall;
-
-// Returns the full user-agent that the stack uses.
-// This is the exact string servers will see.
-+ (NSString *)userAgent;
-
-// Clears CrNet's http cache. The supplied callback, if not nil, is run on an
-// unspecified thread.
-+ (void)clearCacheWithCompletionCallback:(ClearCacheCallback)completionBlock;
-
-@end
-
-#endif  // IOS_CRNET_CRNET_H_
diff --git a/ios/crnet/CrNet.mm b/ios/crnet/CrNet.mm
deleted file mode 100644
index 2aaaef9..0000000
--- a/ios/crnet/CrNet.mm
+++ /dev/null
@@ -1,154 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import "ios/crnet/CrNet.h"
-
-#include "base/logging.h"
-#include "base/strings/sys_string_conversions.h"
-#import "ios/net/crn_http_protocol_handler.h"
-#import "ios/crnet/crnet_environment.h"
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-static CrNetEnvironment* g_chrome_net = NULL;
-
-static BOOL g_http2_enabled = YES;
-static BOOL g_quic_enabled = NO;
-static BOOL g_sdch_enabled = NO;
-static BOOL g_user_agent_partial = NO;
-static NSString* g_user_agent = nil;
-static NSString* g_sdch_pref_store_filename = nil;
-static RequestFilterBlock g_request_filter_block = nil;
-
-@implementation CrNet
-
-+ (void)setHttp2Enabled:(BOOL)http2Enabled {
-  g_http2_enabled = http2Enabled;
-}
-
-+ (void)setQuicEnabled:(BOOL)quicEnabled {
-  g_quic_enabled = quicEnabled;
-}
-
-+ (void)setSDCHEnabled:(BOOL)sdchEnabled
-         withPrefStore:(NSString*)filename {
-  g_sdch_enabled = sdchEnabled;
-  g_sdch_pref_store_filename = filename;
-}
-
-+ (void)setPartialUserAgent:(NSString *)userAgent {
-  [self setUserAgent:userAgent partial:YES];
-}
-
-+ (void)setUserAgent:(NSString*)userAgent partial:(bool)partial {
-  g_user_agent = userAgent;
-  g_user_agent_partial = partial;
-}
-
-+ (void)installInternal {
-  CrNetEnvironment::Initialize();
-  std::string user_agent = base::SysNSStringToUTF8(g_user_agent);
-  g_chrome_net = new CrNetEnvironment(user_agent, g_user_agent_partial == YES);
-
-  g_chrome_net->set_spdy_enabled(g_http2_enabled);
-  g_chrome_net->set_quic_enabled(g_quic_enabled);
-  g_chrome_net->set_sdch_enabled(g_sdch_enabled);
-  if (g_sdch_pref_store_filename) {
-    std::string filename = base::SysNSStringToUTF8(g_sdch_pref_store_filename);
-    g_chrome_net->set_sdch_pref_store_filename(filename);
-  }
-
-  g_chrome_net->Install();
-  g_chrome_net->SetHTTPProtocolHandlerRegistered(true);
-  g_chrome_net->SetRequestFilterBlock(g_request_filter_block);
-}
-
-+ (void)install {
-  static dispatch_once_t onceToken;
-  dispatch_once(&onceToken, ^{
-    if (![NSThread isMainThread]) {
-      dispatch_sync(dispatch_get_main_queue(), ^(void) {
-        [self installInternal];
-      });
-    } else {
-      [self installInternal];
-    }
-  });
-}
-
-+ (void)installIntoSessionConfiguration:(NSURLSessionConfiguration*)config {
-  g_chrome_net->InstallIntoSessionConfiguration(config);
-}
-
-+ (void)installWithPartialUserAgent:(NSString *)partialUserAgent {
-  [self setPartialUserAgent:partialUserAgent];
-  [self install];
-}
-
-+ (void)installWithPartialUserAgent:(NSString *)partialUserAgent
-           enableDataReductionProxy:(BOOL)enableDataReductionProxy {
-  LOG(ERROR) << "enableDataReductionProxy is no longer respected. The "
-      << "functionality has been removed from CrNet.";
-
-  [self setPartialUserAgent:partialUserAgent];
-  [self install];
-}
-
-+ (void)installWithPartialUserAgent:(NSString *)partialUserAgent
-             withRequestFilterBlock:(RequestFilterBlock)requestFilterBlock {
-  [self setPartialUserAgent:partialUserAgent];
-  [self setRequestFilterBlock:requestFilterBlock];
-  [self install];
-}
-
-+ (void)setRequestFilterBlock:(RequestFilterBlock)block {
-  if (g_chrome_net)
-    g_chrome_net->SetRequestFilterBlock(block);
-  else
-    g_request_filter_block = block;
-}
-
-+ (void)uninstall {
-  if (g_chrome_net) {
-    g_chrome_net->SetHTTPProtocolHandlerRegistered(false);
-  }
-}
-
-+ (void)startNetLogToFile:(NSString *)fileName logBytes:(BOOL)logBytes {
-  if (g_chrome_net && [fileName length]) {
-    g_chrome_net->StartNetLog([fileName UTF8String], logBytes);
-  }
-}
-
-+ (void)stopNetLog {
-  if (g_chrome_net) {
-    return g_chrome_net->StopNetLog();
-  }
-}
-
-+ (NSString *)userAgent {
-  if (!g_chrome_net) {
-    return nil;
-  }
-
-  std::string user_agent = g_chrome_net->user_agent();
-  return [NSString stringWithCString:user_agent.c_str()
-                            encoding:[NSString defaultCStringEncoding]];
-}
-
-+ (void)closeAllSpdySessions {
-  if (g_chrome_net) {
-    return g_chrome_net->CloseAllSpdySessions();
-  }
-}
-
-+ (void)clearCacheWithCompletionCallback:(ClearCacheCallback)clearCacheCallback {
-  if (g_chrome_net) {
-    g_chrome_net->ClearCache(clearCacheCallback);
-  }
-}
-
-@end
diff --git a/ios/crnet/DEPS b/ios/crnet/DEPS
deleted file mode 100644
index b9aa4cad..0000000
--- a/ios/crnet/DEPS
+++ /dev/null
@@ -1,8 +0,0 @@
-include_rules = [
-  "+components/prefs",
-  "+ios/crnet",
-  "+ios/net",
-  "+ios/third_party/gcdwebserver",
-  "+ios/web/public/user_agent.h",
-  "+net"
-]
diff --git a/ios/crnet/Info.plist b/ios/crnet/Info.plist
deleted file mode 100644
index c5090813..0000000
--- a/ios/crnet/Info.plist
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-  <key>CFBundleDevelopmentRegion</key>
-  <string>en</string>
-  <key>CFBundleExecutable</key>
-  <string>CrNet</string>
-  <key>CFBundleIdentifier</key>
-  <string>org.chromium.net.CrNet</string>
-  <key>CFBundleInfoDictionaryVersion</key>
-  <string>6.0</string>
-  <key>CFBundleName</key>
-  <string>CrNet</string>
-  <key>CFBundlePackageType</key>
-  <string>FMWK</string>
-  <key>CFBundleShortVersionString</key>
-  <string>1.0</string>
-  <key>CFBundleSignature</key>
-  <string>????</string>
-  <key>CFBundleVersion</key>
-  <string>1.0</string>
-  <key>NSHumanReadableCopyright</key>
-  <string>Copyright 2016 The Chromium Authors. All rights reserved.</string>
-  <key>NSPrincipalClass</key>
-  <string></string>
-</dict>
-</plist>
\ No newline at end of file
diff --git a/ios/crnet/OWNERS b/ios/crnet/OWNERS
deleted file mode 100644
index 0bf94e5..0000000
--- a/ios/crnet/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-droger@chromium.org
-ellyjones@chromium.org
-mef@chromium.org
diff --git a/ios/crnet/Resources/Localization/am.lproj/Localizable.strings b/ios/crnet/Resources/Localization/am.lproj/Localizable.strings
deleted file mode 100644
index ba55b06..0000000
--- a/ios/crnet/Resources/Localization/am.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "am,en-GB,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/ar.lproj/Localizable.strings b/ios/crnet/Resources/Localization/ar.lproj/Localizable.strings
deleted file mode 100644
index dcd3304..0000000
--- a/ios/crnet/Resources/Localization/ar.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "ar,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/bg.lproj/Localizable.strings b/ios/crnet/Resources/Localization/bg.lproj/Localizable.strings
deleted file mode 100644
index 407c27b5..0000000
--- a/ios/crnet/Resources/Localization/bg.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "bg-BG,bg";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/bn.lproj/Localizable.strings b/ios/crnet/Resources/Localization/bn.lproj/Localizable.strings
deleted file mode 100644
index 08a6464..0000000
--- a/ios/crnet/Resources/Localization/bn.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "bn-IN,bn,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/ca.lproj/Localizable.strings b/ios/crnet/Resources/Localization/ca.lproj/Localizable.strings
deleted file mode 100644
index bec5e211..0000000
--- a/ios/crnet/Resources/Localization/ca.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "ca-ES,ca";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/cs.lproj/Localizable.strings b/ios/crnet/Resources/Localization/cs.lproj/Localizable.strings
deleted file mode 100644
index 665a4e3a..0000000
--- a/ios/crnet/Resources/Localization/cs.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "cs-CZ,cs";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/da.lproj/Localizable.strings b/ios/crnet/Resources/Localization/da.lproj/Localizable.strings
deleted file mode 100644
index 428e5f7..0000000
--- a/ios/crnet/Resources/Localization/da.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "da-DK,da,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/de.lproj/Localizable.strings b/ios/crnet/Resources/Localization/de.lproj/Localizable.strings
deleted file mode 100644
index ca69ecb4..0000000
--- a/ios/crnet/Resources/Localization/de.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "de-DE,de,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/el.lproj/Localizable.strings b/ios/crnet/Resources/Localization/el.lproj/Localizable.strings
deleted file mode 100644
index 450fd28..0000000
--- a/ios/crnet/Resources/Localization/el.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "el-GR,el";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/en-GB.lproj/Localizable.strings b/ios/crnet/Resources/Localization/en-GB.lproj/Localizable.strings
deleted file mode 100644
index 790ff2c..0000000
--- a/ios/crnet/Resources/Localization/en-GB.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "en-GB,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/en.lproj/Localizable.strings b/ios/crnet/Resources/Localization/en.lproj/Localizable.strings
deleted file mode 100644
index b379815..0000000
--- a/ios/crnet/Resources/Localization/en.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. DO NOT TRANSLATE. */
-"IDS_ACCEPT_LANGUAGES" = "en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/es-419.lproj/Localizable.strings b/ios/crnet/Resources/Localization/es-419.lproj/Localizable.strings
deleted file mode 100644
index 347bc579..0000000
--- a/ios/crnet/Resources/Localization/es-419.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "es-419,es";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/es.lproj/Localizable.strings b/ios/crnet/Resources/Localization/es.lproj/Localizable.strings
deleted file mode 100644
index 1ed553b7..0000000
--- a/ios/crnet/Resources/Localization/es.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "es-ES,es";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/et.lproj/Localizable.strings b/ios/crnet/Resources/Localization/et.lproj/Localizable.strings
deleted file mode 100644
index 6260779..0000000
--- a/ios/crnet/Resources/Localization/et.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "et-EE,et,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/fa.lproj/Localizable.strings b/ios/crnet/Resources/Localization/fa.lproj/Localizable.strings
deleted file mode 100644
index 69d343f..0000000
--- a/ios/crnet/Resources/Localization/fa.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "fa,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/fi.lproj/Localizable.strings b/ios/crnet/Resources/Localization/fi.lproj/Localizable.strings
deleted file mode 100644
index 3c35a79..0000000
--- a/ios/crnet/Resources/Localization/fi.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "fi-FI,fi,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/fil.lproj/Localizable.strings b/ios/crnet/Resources/Localization/fil.lproj/Localizable.strings
deleted file mode 100644
index 6a90add..0000000
--- a/ios/crnet/Resources/Localization/fil.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "fil,fil-PH,tl,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/fr.lproj/Localizable.strings b/ios/crnet/Resources/Localization/fr.lproj/Localizable.strings
deleted file mode 100644
index 1cf4700..0000000
--- a/ios/crnet/Resources/Localization/fr.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "fr-FR,fr,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/gu.lproj/Localizable.strings b/ios/crnet/Resources/Localization/gu.lproj/Localizable.strings
deleted file mode 100644
index b8439e85..0000000
--- a/ios/crnet/Resources/Localization/gu.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "gu-IN,gu,hi-IN,hi,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/he.lproj/Localizable.strings b/ios/crnet/Resources/Localization/he.lproj/Localizable.strings
deleted file mode 100644
index 23c6a0d..0000000
--- a/ios/crnet/Resources/Localization/he.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "he-IL,he,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/hi.lproj/Localizable.strings b/ios/crnet/Resources/Localization/hi.lproj/Localizable.strings
deleted file mode 100644
index 28466ff..0000000
--- a/ios/crnet/Resources/Localization/hi.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "hi-IN,hi,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/hr.lproj/Localizable.strings b/ios/crnet/Resources/Localization/hr.lproj/Localizable.strings
deleted file mode 100644
index db8c1e6..0000000
--- a/ios/crnet/Resources/Localization/hr.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "hr-HR,hr,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/hu.lproj/Localizable.strings b/ios/crnet/Resources/Localization/hu.lproj/Localizable.strings
deleted file mode 100644
index 3b86667..0000000
--- a/ios/crnet/Resources/Localization/hu.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "hu-HU,hu,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/id.lproj/Localizable.strings b/ios/crnet/Resources/Localization/id.lproj/Localizable.strings
deleted file mode 100644
index 7af26cef..0000000
--- a/ios/crnet/Resources/Localization/id.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "id-ID,id,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/it.lproj/Localizable.strings b/ios/crnet/Resources/Localization/it.lproj/Localizable.strings
deleted file mode 100644
index fd855c0..0000000
--- a/ios/crnet/Resources/Localization/it.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "it-IT,it,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/ja.lproj/Localizable.strings b/ios/crnet/Resources/Localization/ja.lproj/Localizable.strings
deleted file mode 100644
index 6a1779e..0000000
--- a/ios/crnet/Resources/Localization/ja.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "ja,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/kn.lproj/Localizable.strings b/ios/crnet/Resources/Localization/kn.lproj/Localizable.strings
deleted file mode 100644
index 167d19ca..0000000
--- a/ios/crnet/Resources/Localization/kn.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "kn-IN,kn,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/ko.lproj/Localizable.strings b/ios/crnet/Resources/Localization/ko.lproj/Localizable.strings
deleted file mode 100644
index c5e8d4f2..0000000
--- a/ios/crnet/Resources/Localization/ko.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "ko-KR,ko,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/lt.lproj/Localizable.strings b/ios/crnet/Resources/Localization/lt.lproj/Localizable.strings
deleted file mode 100644
index 857146a..0000000
--- a/ios/crnet/Resources/Localization/lt.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "lt,en-US,en,ru,pl";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/lv.lproj/Localizable.strings b/ios/crnet/Resources/Localization/lv.lproj/Localizable.strings
deleted file mode 100644
index 1efd5e84..0000000
--- a/ios/crnet/Resources/Localization/lv.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "lv-LV,lv,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/ml.lproj/Localizable.strings b/ios/crnet/Resources/Localization/ml.lproj/Localizable.strings
deleted file mode 100644
index 4382668..0000000
--- a/ios/crnet/Resources/Localization/ml.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "ml-IN,ml,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/mr.lproj/Localizable.strings b/ios/crnet/Resources/Localization/mr.lproj/Localizable.strings
deleted file mode 100644
index fbf98d7..0000000
--- a/ios/crnet/Resources/Localization/mr.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "mr-IN,mr,hi-IN,hi,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/ms.lproj/Localizable.strings b/ios/crnet/Resources/Localization/ms.lproj/Localizable.strings
deleted file mode 100644
index a8b6d58..0000000
--- a/ios/crnet/Resources/Localization/ms.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. DO NOT TRANSLATE. */
-"IDS_ACCEPT_LANGUAGES" = "ms,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/nb.lproj/Localizable.strings b/ios/crnet/Resources/Localization/nb.lproj/Localizable.strings
deleted file mode 100644
index 4e3271b6..0000000
--- a/ios/crnet/Resources/Localization/nb.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "nb-NO,nb,no,nn,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/nl.lproj/Localizable.strings b/ios/crnet/Resources/Localization/nl.lproj/Localizable.strings
deleted file mode 100644
index dca54fe..0000000
--- a/ios/crnet/Resources/Localization/nl.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "nl-NL,nl,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/pl.lproj/Localizable.strings b/ios/crnet/Resources/Localization/pl.lproj/Localizable.strings
deleted file mode 100644
index f9ea84e1..0000000
--- a/ios/crnet/Resources/Localization/pl.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "pl-PL,pl,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/pt-BR.lproj/Localizable.strings b/ios/crnet/Resources/Localization/pt-BR.lproj/Localizable.strings
deleted file mode 100644
index 8b04250..0000000
--- a/ios/crnet/Resources/Localization/pt-BR.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "pt-BR,pt,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/pt-PT.lproj/Localizable.strings b/ios/crnet/Resources/Localization/pt-PT.lproj/Localizable.strings
deleted file mode 100644
index 2e0d86c..0000000
--- a/ios/crnet/Resources/Localization/pt-PT.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "pt-PT,pt,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/pt.lproj/Localizable.strings b/ios/crnet/Resources/Localization/pt.lproj/Localizable.strings
deleted file mode 100644
index fb3c1ebd..0000000
--- a/ios/crnet/Resources/Localization/pt.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. DO NOT TRANSLATE. */
-"IDS_ACCEPT_LANGUAGES" = "pt-PT,pt,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/ro.lproj/Localizable.strings b/ios/crnet/Resources/Localization/ro.lproj/Localizable.strings
deleted file mode 100644
index 7428ce5..0000000
--- a/ios/crnet/Resources/Localization/ro.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "ro-RO,ro,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/ru.lproj/Localizable.strings b/ios/crnet/Resources/Localization/ru.lproj/Localizable.strings
deleted file mode 100644
index 2d56449..0000000
--- a/ios/crnet/Resources/Localization/ru.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "ru-RU,ru,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/sk.lproj/Localizable.strings b/ios/crnet/Resources/Localization/sk.lproj/Localizable.strings
deleted file mode 100644
index 5dff353f..0000000
--- a/ios/crnet/Resources/Localization/sk.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "sk-SK,sk,cs,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/sl.lproj/Localizable.strings b/ios/crnet/Resources/Localization/sl.lproj/Localizable.strings
deleted file mode 100644
index 811ab06f..0000000
--- a/ios/crnet/Resources/Localization/sl.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "sl-SI,sl,en-GB,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/sr.lproj/Localizable.strings b/ios/crnet/Resources/Localization/sr.lproj/Localizable.strings
deleted file mode 100644
index ff18f14..0000000
--- a/ios/crnet/Resources/Localization/sr.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "sr-RS,sr,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/sv.lproj/Localizable.strings b/ios/crnet/Resources/Localization/sv.lproj/Localizable.strings
deleted file mode 100644
index 3daf55fc..0000000
--- a/ios/crnet/Resources/Localization/sv.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "sv-SE,sv,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/sw.lproj/Localizable.strings b/ios/crnet/Resources/Localization/sw.lproj/Localizable.strings
deleted file mode 100644
index ef6b492..0000000
--- a/ios/crnet/Resources/Localization/sw.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "sw,en-GB,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/ta.lproj/Localizable.strings b/ios/crnet/Resources/Localization/ta.lproj/Localizable.strings
deleted file mode 100644
index 2bde0146..0000000
--- a/ios/crnet/Resources/Localization/ta.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "ta-IN,ta,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/te.lproj/Localizable.strings b/ios/crnet/Resources/Localization/te.lproj/Localizable.strings
deleted file mode 100644
index 38fb4a4..0000000
--- a/ios/crnet/Resources/Localization/te.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "te-IN,te,hi-IN,hi,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/th.lproj/Localizable.strings b/ios/crnet/Resources/Localization/th.lproj/Localizable.strings
deleted file mode 100644
index 464b6370..0000000
--- a/ios/crnet/Resources/Localization/th.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "th-TH,th";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/tr.lproj/Localizable.strings b/ios/crnet/Resources/Localization/tr.lproj/Localizable.strings
deleted file mode 100644
index b5289e2a..0000000
--- a/ios/crnet/Resources/Localization/tr.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "tr-TR,tr,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/uk.lproj/Localizable.strings b/ios/crnet/Resources/Localization/uk.lproj/Localizable.strings
deleted file mode 100644
index 1fe6381..0000000
--- a/ios/crnet/Resources/Localization/uk.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "uk-UA,uk,ru,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/vi.lproj/Localizable.strings b/ios/crnet/Resources/Localization/vi.lproj/Localizable.strings
deleted file mode 100644
index 082f76da..0000000
--- a/ios/crnet/Resources/Localization/vi.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. */
-"IDS_ACCEPT_LANGUAGES" = "vi-VN,vi,fr-FR,fr,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/zh-Hans.lproj/Localizable.strings b/ios/crnet/Resources/Localization/zh-Hans.lproj/Localizable.strings
deleted file mode 100644
index 0a14ff7..0000000
--- a/ios/crnet/Resources/Localization/zh-Hans.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. DO NOT TRANSLATE. */
-"IDS_ACCEPT_LANGUAGES" = "zh-CN,zh";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/zh-Hant.lproj/Localizable.strings b/ios/crnet/Resources/Localization/zh-Hant.lproj/Localizable.strings
deleted file mode 100644
index fadad918..0000000
--- a/ios/crnet/Resources/Localization/zh-Hant.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. DO NOT TRANSLATE. */
-"IDS_ACCEPT_LANGUAGES" = "zh-TW,zh,en-US,en";
\ No newline at end of file
diff --git a/ios/crnet/Resources/Localization/zh.lproj/Localizable.strings b/ios/crnet/Resources/Localization/zh.lproj/Localizable.strings
deleted file mode 100644
index 0a14ff7..0000000
--- a/ios/crnet/Resources/Localization/zh.lproj/Localizable.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-/* These values are copied from Chrome's .xtb files, this is so the same values are used in the |Accept-Language| header. Key name matches Chrome's. DO NOT TRANSLATE. */
-"IDS_ACCEPT_LANGUAGES" = "zh-CN,zh";
\ No newline at end of file
diff --git a/ios/crnet/Resources/README b/ios/crnet/Resources/README
deleted file mode 100644
index 681b853..0000000
--- a/ios/crnet/Resources/README
+++ /dev/null
@@ -1,9 +0,0 @@
-This localization directory contains language strings taken from Chrome. These
-language strings are taken from Chrome's *.xtb files with the key
-IDS_ACCEPT_LANGUAGES.
-
-DO NOT translate strings with a IDS_ACCEPT_LANGUAGES key from these .strings
-files in the translation console.
-
-On top of Chrome's language list, the following languages were added:
-"pt" "ms" "zh"
diff --git a/ios/crnet/build.py b/ios/crnet/build.py
deleted file mode 100755
index 12874bf..0000000
--- a/ios/crnet/build.py
+++ /dev/null
@@ -1,322 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-import os
-import shutil
-import subprocess
-import sys
-import tempfile
-import time
-
-
-SUPPORTED_ARCHES = ['i386', 'x86_64', 'armv7', 'arm64']
-
-
-class SubprocessError(Exception):
-  pass
-
-
-class ConfigurationError(Exception):
-  pass
-
-
-def out_directories(root):
-  """Returns all output directories containing crnet objects under root.
-
-  Currently this list is just hardcoded.
-
-  Args:
-    root: prefix for output directories.
-  """
-  out_dirs = ['Release-iphoneos', 'Release-iphonesimulator']
-  return map(lambda x: os.path.join(root, 'out', x), out_dirs)
-
-
-def check_command(command):
-  """Runs a command, raising an exception if it fails.
-
-  If the command returns a nonzero exit code, prints any data the command
-  emitted on stdout and stderr.
-
-  Args:
-    command: command to execute, in argv format.
-
-  Raises:
-    SubprocessError: the specified command returned nonzero exit status.
-  """
-  p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-  (stdout, stderr) = p.communicate()
-  if p.returncode == 0:
-    return
-  message = 'Command failed: {0} (status {1})'.format(command, p.returncode)
-  print message
-  print 'stdout: {0}'.format(stdout)
-  print 'stderr: {0}'.format(stderr)
-  raise SubprocessError(message)
-
-
-def file_contains_string(path, string):
-  """Returns whether the file named by path contains string.
-
-  Args:
-    path: path of the file to search.
-    string: string to search the file for.
-
-  Returns:
-    True if file contains string, False otherwise.
-  """
-  with open(path, 'r') as f:
-    for line in f:
-      if string in line:
-        return True
-  return False
-
-
-def is_object_filename(filename):
-  """Returns whether the given filename names an object file.
-
-  Args:
-    filename: filename to inspect.
-
-  Returns:
-    True if filename names an object file, false otherwise.
-  """
-  (_, ext) = os.path.splitext(filename)
-  return ext in ('.a', '.o')
-
-
-class Step(object):
-  """Represents a single step of the crnet build process.
-
-  This parent class exists only to define the interface Steps present and keep
-  track of elapsed time for each step. Subclasses of Step should override the
-  run() method, which is called internally by start().
-
-  Attributes:
-    name: human-readable name of this step, used in debug output.
-    started_at: seconds since epoch that this step started running at.
-  """
-  def __init__(self, name):
-    self._name = name
-    self._started_at = None
-    self._ended_at = None
-
-  @property
-  def name(self):
-    return self._name
-
-  def start(self):
-    """Start running this step.
-
-    This method keeps track of how long the run() method takes to run and emits
-    the elapsed time after run() returns.
-    """
-    self._started_at = time.time()
-    print '{0}: '.format(self._name),
-    sys.stdout.flush()
-    self._run()
-    self._ended_at = time.time()
-    print '{0:.2f}s'.format(self._ended_at - self._started_at)
-
-  def _run(self):
-    """Actually run this step.
-
-    Subclasses should override this method to implement their own step logic.
-    """
-    raise NotImplementedError
-
-
-class CleanStep(Step):
-  """Clean the build output directories.
-
-  This step deletes intermediates generated by the build process. Some of these
-  intermediates (crnet_consumer.app and crnet_resources.bundle) are directories,
-  which contain files ninja doesn't know and hence won't remove, so the run()
-  method here explicitly deletes those directories before running 'ninja -t
-  clean'.
-
-  Attributes:
-    dirs: list of output directories to clean.
-  """
-  def __init__(self, root):
-    super(CleanStep, self).__init__('clean')
-    self._dirs = out_directories(root)
-
-  def _run(self):
-    """Runs the clean step.
-
-    Deletes crnet_consumer.app and crnet_resources.bundle in each output
-    directory and runs 'ninja -t clean' in each output directory.
-    """
-    for d in self._dirs:
-      if os.path.exists(os.path.join(d, 'crnet_consumer.app')):
-        shutil.rmtree(os.path.join(d, 'crnet_consumer.app'))
-      if os.path.exists(os.path.join(d, 'crnet_resources.bundle')):
-        shutil.rmtree(os.path.join(d, 'crnet_resources.bundle'))
-      check_command(['ninja', '-C', d, '-t', 'clean'])
-
-
-class HooksStep(Step):
-  """Validates the gyp config and reruns gclient hooks.
-
-  Attributes:
-    root: directory to find gyp config under.
-  """
-  def __init__(self, root):
-    super(HooksStep, self).__init__('hooks')
-    self._root = root
-
-  def _run(self):
-    """Runs the hooks step.
-
-    Checks that root/build/common.gypi contains target_subarch = both in a crude
-    way, then calls 'gclient runhooks'. TODO(ellyjones): parse common.gypi in a
-    more robust way.
-
-    Raises:
-      ConfigurationError: if target_subarch != both
-    """
-    common_gypi = os.path.join(self._root, 'build', 'common.gypi')
-    if not file_contains_string(common_gypi, "'target_subarch%': 'both'"):
-      raise ConfigurationError('target_subarch must be both in {0}'.format(
-          common_gypi))
-    check_command(['gclient', 'runhooks'])
-
-
-class BuildStep(Step):
-  """Builds all the intermediate crnet binaries.
-
-  All the hard work of this step is done by ninja; this step just shells out to
-  ninja to build the crnet_pack target.
-
-  Attributes:
-    dirs: output directories to run ninja in.
-  """
-  def __init__(self, root):
-    super(BuildStep, self).__init__('build')
-    self._dirs = out_directories(root)
-
-  def _run(self):
-    """Runs the build step.
-
-    For each output directory, run ninja to build the crnet_pack target in that
-    directory.
-    """
-    for d in self._dirs:
-      check_command(['ninja', '-C', d, 'crnet_pack'])
-
-
-class PackageStep(Step):
-  """Packages the built object files for release.
-
-  The release format is a tarball, containing one gzipped tarball per
-  architecture and a manifest file, which lists metadata about the build.
-
-  Attributes:
-    outdirs: directories containing built object files.
-    workdir: temporary working directory. Deleted at end of the step.
-    archdir: temporary directory under workdir. Used for collecting per-arch
-             binaries.
-    proddir: temporary directory under workdir. Used for intermediate per-arch
-             tarballs.
-  """
-  def __init__(self, root, outfile):
-    super(PackageStep, self).__init__('package')
-    self._outdirs = out_directories(root)
-    self._outfile = outfile
-
-  def _run(self):
-    """Runs the package step.
-
-    Packages each architecture from |root| into an individual .tar.gz file, then
-    packages all the .tar.gz files into one .tar file, which is written to
-    |outfile|.
-    """
-    (workdir, archdir, proddir) = self.create_work_dirs()
-    for arch in SUPPORTED_ARCHES:
-      self.package_arch(archdir, proddir, arch)
-    self.package(proddir)
-    shutil.rmtree(workdir)
-
-  def create_work_dirs(self):
-    """Creates working directories and returns their paths."""
-    workdir = tempfile.mkdtemp()
-    archdir = os.path.join(workdir, 'arch')
-    proddir = os.path.join(workdir, 'prod')
-    os.mkdir(archdir)
-    os.mkdir(proddir)
-    return (workdir, archdir, proddir)
-
-  def object_files_for_arch(self, arch):
-    """Returns a list of object files for the given architecture.
-
-    Under each outdir d, per-arch files are stored in d/arch, and object files
-    for a given arch contain the arch's name as a substring.
-
-    Args:
-      arch: architecture name. Must be in SUPPORTED_ARCHES.
-
-    Returns:
-      List of full pathnames to object files in outdirs for the named arch.
-    """
-    arch_files = []
-    for d in self._outdirs:
-      files = os.listdir(os.path.join(d, 'arch'))
-      for f in filter(is_object_filename, files):
-        if arch in f:
-          arch_files.append(os.path.join(d, 'arch', f))
-    return arch_files
-
-  def package_arch(self, archdir, proddir, arch):
-    """Packages an individual architecture.
-
-    Copies all the object files for the specified arch into a working directory
-    under self.archdir, then tars them up into a gzipped tarball under
-    self.proddir.
-
-    Args:
-      archdir: directory to stage architecture files in.
-      proddir: directory to stage result tarballs in.
-      arch: architecture name to package. Must be in SUPPORTED_ARCHES.
-    """
-    arch_files = self.object_files_for_arch(arch)
-    os.mkdir(os.path.join(archdir, arch))
-    for f in arch_files:
-      shutil.copy(f, os.path.join(archdir, arch))
-    out_filename = os.path.join(proddir, '{0}.tar.gz'.format(arch))
-    check_command(['tar', '-C', archdir, '-czf', out_filename, arch])
-
-  def package(self, proddir):
-    """Final packaging step. Packages all the arch tarballs into one tarball."""
-    arch_tarballs = []
-    for a in SUPPORTED_ARCHES:
-      arch_tarballs.append('{0}.tar.gz'.format(a))
-    check_command(['tar', '-C', proddir, '-cf', self._outfile] +
-                  arch_tarballs)
-
-
-def main():
-  step_classes = {
-    'clean': lambda: CleanStep(args.rootdir),
-    'hooks': lambda: HooksStep(args.rootdir),
-    'build': lambda: BuildStep(args.rootdir),
-    'package': lambda: PackageStep(args.rootdir, args.outfile)
-  }
-  parser = argparse.ArgumentParser(description='Build and package crnet.')
-  parser.add_argument('--outfile', dest='outfile', default='crnet.tar',
-                      help='Output file to generate (default: crnet.tar)')
-  parser.add_argument('--rootdir', dest='rootdir', default='../..',
-                      help='Root directory to build from (default: ../..)')
-  parser.add_argument('steps', metavar='step', nargs='*')
-  args = parser.parse_args()
-  step_names = args.steps or ['clean', 'hooks', 'build', 'package']
-  steps = [step_classes[x]() for x in step_names]
-  for step in steps:
-    step.start()
-
-
-if __name__ == '__main__':
-  main()
diff --git a/ios/crnet/crnet_environment.h b/ios/crnet/crnet_environment.h
deleted file mode 100644
index ed954bfc..0000000
--- a/ios/crnet/crnet_environment.h
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CRNET_CRNET_ENVIRONMENT_H_
-#define IOS_CRNET_CRNET_ENVIRONMENT_H_
-
-#include <memory>
-
-#include "base/files/file_path.h"
-#include "base/macros.h"
-#include "base/message_loop/message_loop.h"
-#include "base/synchronization/waitable_event.h"
-#include "base/threading/thread.h"
-#import "ios/crnet/CrNet.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_context.h"
-
-class JsonPrefStore;
-
-namespace net {
-class CookieStore;
-class NetworkChangeNotifier;
-class NetLog;
-class ProxyConfigService;
-class SdchManager;
-class SdchOwner;
-class URLRequestContextGetter;
-class WriteToFileNetLogObserver;
-}
-
-class CrNetHttpProtocolHandlerDelegate;
-
-// CrNetEnvironment contains all the network stack configuration
-// and initialization.
-class CrNetEnvironment {
- public:
-  // Must be called on the main thread.
-  static void Initialize();
-
-  // If |user_agent_partial| is true, then |user_agent| will be used to
-  // generate the user-agent, otherwise it will be used directly.
-  CrNetEnvironment(const std::string& user_agent, bool user_agent_partial);
-  ~CrNetEnvironment();
-
-  // Installs this CrNet environment so requests are intercepted.
-  // Can only be called once; to enable/disable CrNet at runtime, use
-  // SetHTTPProtocolHandlerRegistered.
-  void Install();
-
-  // Installs this CrNet environment into the supplied
-  // NSURLSessionConfiguration. Settings are inherited from the shared
-  // NSURLSessionConfiguration, which Install() affects.
-  void InstallIntoSessionConfiguration(NSURLSessionConfiguration* config);
-
-  // The full user-agent.
-  std::string user_agent();
-
-  // Returns the global request context getter for use in the network stack.
-  //
-  // The request context gathers all the settings needed to do an actual network
-  // request (cache type and path, cookies store, proxy setting ...).
-  // Chrome network stacks supports multiple active contexts, and this is used
-  // for example to separate Incognito data from the main profile data.
-  // CrNetEnvironment only implement one request context for now, but it can be
-  // extended in the future.
-  net::URLRequestContextGetter* GetMainContextGetter();
-
-  // Enables or disables the HTTP protocol handler.
-  //
-  // When the HTTP protocol handler is registered, it will be used for all the
-  // network requests the application does (including requests from UIWebView).
-  void SetHTTPProtocolHandlerRegistered(bool registered);
-
-  // Creates a new net log (overwrites existing file with this name). If
-  // actively logging, this call is ignored.
-  void StartNetLog(base::FilePath::StringType file_name, bool log_bytes);
-  // Stops logging and flushes file. If not currently logging this call is
-  // ignored.
-  void StopNetLog();
-  // Closes all existing SPDY sessions with ERR_ABORTED.
-  void CloseAllSpdySessions();
-
-  // Sets the block used to determine whether or not CrNet should handle the
-  // request. If this is not set, CrNet will handle all requests.
-  // Must not be called while requests are in progress.
-  void SetRequestFilterBlock(RequestFilterBlock block);
-
-  // Setters and getters for |spdy_enabled_|, |quic_enabled_|, and
-  // |forced_quic_origin_|. These only have any effect before Install() is
-  // called.
-  void set_spdy_enabled(bool enabled) { spdy_enabled_ = enabled; }
-  void set_quic_enabled(bool enabled) { quic_enabled_ = enabled; }
-  void set_sdch_enabled(bool enabled) { sdch_enabled_ = enabled; }
-  void set_sdch_pref_store_filename(const std::string& pref_store) {
-    sdch_pref_store_filename_ = pref_store;
-  }
-
-  bool spdy_enabled() const { return spdy_enabled_; }
-  bool quic_enabled() const { return quic_enabled_; }
-  bool sdch_enabled() const { return sdch_enabled_; }
-
-  // Clears the network stack's disk cache.
-  void ClearCache(ClearCacheCallback callback);
-
- private:
-  // Runs a closure on the network thread.
-  void PostToNetworkThread(const tracked_objects::Location& from_here,
-                           const base::Closure& task);
-
-  // Configures SDCH on the network thread. If SDCH is enabled, sets up
-  // SdchManager, and configures persistence as needed.
-  void ConfigureSdchOnNetworkThread();
-
-  // Performs initialization tasks that must happen on the network thread.
-  void InitializeOnNetworkThread();
-
-  // Runs a closure on the file user blocking thread.
-  void PostToFileUserBlockingThread(const tracked_objects::Location& from_here,
-                                    const base::Closure& task);
-
-  // Helper methods that start/stop net-internals logging on the file
-  // user blocking thread.
-  void StartNetLogInternal(base::FilePath::StringType file_name,
-      bool log_bytes);
-  void StopNetLogInternal();
-
-  // Returns the HttpNeteworkSession object from the passed in
-  // URLRequestContext or NULL if none exists.
-  net::HttpNetworkSession* GetHttpNetworkSession(
-      net::URLRequestContext* context);
-
-  // Helper method that closes all current SPDY sessions on the network IO
-  // thread.
-  void CloseAllSpdySessionsInternal();
-
-  bool spdy_enabled_;
-  bool quic_enabled_;
-  bool sdch_enabled_;
-  std::string sdch_pref_store_filename_;
-
-  static CrNetEnvironment* chrome_net_;
-  std::unique_ptr<base::Thread> network_io_thread_;
-  std::unique_ptr<base::Thread> network_cache_thread_;
-  std::unique_ptr<base::Thread> file_thread_;
-  std::unique_ptr<base::Thread> file_user_blocking_thread_;
-  std::unique_ptr<net::SdchManager> sdch_manager_;
-  std::unique_ptr<net::SdchOwner> sdch_owner_;
-  scoped_refptr<base::SequencedTaskRunner> pref_store_worker_pool_;
-  scoped_refptr<JsonPrefStore> net_pref_store_;
-  std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
-  std::unique_ptr<net::ProxyConfigService> proxy_config_service_;
-  std::unique_ptr<net::HttpServerProperties> http_server_properties_;
-  std::unique_ptr<net::CookieStore> cookie_store_;
-  scoped_refptr<net::URLRequestContextGetter> main_context_getter_;
-  std::unique_ptr<net::URLRequestContext> main_context_;
-  std::unique_ptr<CrNetHttpProtocolHandlerDelegate>
-      http_protocol_handler_delegate_;
-  std::string user_agent_;
-  bool user_agent_partial_;
-  std::unique_ptr<net::NetLog> net_log_;
-  std::unique_ptr<net::WriteToFileNetLogObserver> net_log_observer_;
-
-  DISALLOW_COPY_AND_ASSIGN(CrNetEnvironment);
-};
-
-#endif  // IOS_CRNET_CRNET_ENVIRONMENT_H_
diff --git a/ios/crnet/crnet_environment.mm b/ios/crnet/crnet_environment.mm
deleted file mode 100644
index 02bfd737..0000000
--- a/ios/crnet/crnet_environment.mm
+++ /dev/null
@@ -1,521 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ios/crnet/crnet_environment.h"
-
-#import <Foundation/Foundation.h>
-
-#include <utility>
-
-#include "base/at_exit.h"
-#include "base/atomicops.h"
-#include "base/command_line.h"
-#include "base/feature_list.h"
-#include "base/files/file_path.h"
-#include "base/files/file_util.h"
-#include "base/files/scoped_file.h"
-#include "base/json/json_writer.h"
-#include "base/mac/bind_objc_block.h"
-#include "base/mac/bundle_locations.h"
-#include "base/mac/foundation_util.h"
-#include "base/mac/scoped_block.h"
-#include "base/macros.h"
-#include "base/memory/ptr_util.h"
-#include "base/metrics/statistics_recorder.h"
-#include "base/path_service.h"
-#include "base/single_thread_task_runner.h"
-#include "components/prefs/json_pref_store.h"
-#include "components/prefs/pref_filter.h"
-#include "ios/crnet/sdch_owner_pref_storage.h"
-#include "ios/net/cookies/cookie_store_ios.h"
-#include "ios/net/crn_http_protocol_handler.h"
-#include "ios/net/empty_nsurlcache.h"
-#include "ios/net/http_cache_helper.h"
-#include "ios/net/request_tracker.h"
-#include "ios/web/public/user_agent.h"
-#include "net/base/net_errors.h"
-#include "net/base/network_change_notifier.h"
-#include "net/base/sdch_manager.h"
-#include "net/cert/cert_verifier.h"
-#include "net/cert/ct_known_logs.h"
-#include "net/cert/ct_log_verifier.h"
-#include "net/cert/ct_policy_enforcer.h"
-#include "net/cert/ct_verifier.h"
-#include "net/cert/multi_log_ct_verifier.h"
-#include "net/cookies/cookie_store.h"
-#include "net/http/http_auth_handler_factory.h"
-#include "net/http/http_cache.h"
-#include "net/http/http_server_properties_impl.h"
-#include "net/http/http_stream_factory.h"
-#include "net/http/http_util.h"
-#include "net/log/net_log.h"
-#include "net/log/write_to_file_net_log_observer.h"
-#include "net/net_features.h"
-#include "net/proxy/proxy_service.h"
-#include "net/sdch/sdch_owner.h"
-#include "net/ssl/channel_id_service.h"
-#include "net/ssl/default_channel_id_store.h"
-#include "net/ssl/ssl_config_service_defaults.h"
-#include "net/url_request/data_protocol_handler.h"
-#include "net/url_request/file_protocol_handler.h"
-#include "net/url_request/sdch_dictionary_fetcher.h"
-#include "net/url_request/static_http_user_agent_settings.h"
-#include "net/url_request/url_request_context_getter.h"
-#include "net/url_request/url_request_context_storage.h"
-#include "net/url_request/url_request_job_factory_impl.h"
-#include "url/url_features.h"
-#include "url/url_util.h"
-
-#if !BUILDFLAG(USE_PLATFORM_ICU_ALTERNATIVES)
-#include "base/i18n/icu_util.h"  // nogncheck
-#endif
-
-#if !defined(__has_feature) || !__has_feature(objc_arc)
-#error "This file requires ARC support."
-#endif
-
-namespace {
-
-base::AtExitManager* g_at_exit_ = nullptr;
-
-// Request context getter for CrNet.
-class CrNetURLRequestContextGetter : public net::URLRequestContextGetter {
- public:
-  CrNetURLRequestContextGetter(
-      net::URLRequestContext* context,
-      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
-      : context_(context), task_runner_(task_runner) {}
-
-  net::URLRequestContext* GetURLRequestContext() override { return context_; }
-
-  scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
-      const override {
-    return task_runner_;
-  }
- private:
-  // Must be called on the IO thread.
-  ~CrNetURLRequestContextGetter() override {}
-
-  net::URLRequestContext* context_;
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
-  DISALLOW_COPY_AND_ASSIGN(CrNetURLRequestContextGetter);
-};
-
-}  // namespace
-
-// net::HTTPProtocolHandlerDelegate for CrNet.
-class CrNetHttpProtocolHandlerDelegate
-    : public net::HTTPProtocolHandlerDelegate {
- public:
-  CrNetHttpProtocolHandlerDelegate(net::URLRequestContextGetter* getter,
-                                   RequestFilterBlock filter)
-      : getter_(getter), filter_([filter copy]) {}
-
- private:
-  // net::HTTPProtocolHandlerDelegate implementation:
-  bool CanHandleRequest(NSURLRequest* request) override {
-    // Don't advertise support for file:// URLs for now.
-    // This broke some time ago but it's not clear how to fix it at the moment.
-    // http://crbug.com/480620
-    if ([[[request URL] scheme] caseInsensitiveCompare:@"file"] ==
-        NSOrderedSame) {
-      return false;
-    }
-    if (filter_) {
-      return filter_(request);
-    }
-    return true;
-  }
-
-  bool IsRequestSupported(NSURLRequest* request) override {
-    NSString* scheme = [[request URL] scheme];
-    if (!scheme)
-      return false;
-    return [scheme caseInsensitiveCompare:@"data"] == NSOrderedSame ||
-           [scheme caseInsensitiveCompare:@"http"] == NSOrderedSame ||
-           [scheme caseInsensitiveCompare:@"https"] == NSOrderedSame;
-  }
-
-  net::URLRequestContextGetter* GetDefaultURLRequestContext() override {
-    return getter_.get();
-  }
-
-  scoped_refptr<net::URLRequestContextGetter> getter_;
-  RequestFilterBlock filter_;
-};
-
-void CrNetEnvironment::PostToNetworkThread(
-    const tracked_objects::Location& from_here,
-    const base::Closure& task) {
-  network_io_thread_->task_runner()->PostTask(from_here, task);
-}
-
-void CrNetEnvironment::PostToFileUserBlockingThread(
-    const tracked_objects::Location& from_here,
-    const base::Closure& task) {
-  file_user_blocking_thread_->task_runner()->PostTask(from_here, task);
-}
-
-// static
-void CrNetEnvironment::Initialize() {
-  DCHECK_EQ([NSThread currentThread], [NSThread mainThread]);
-  if (!g_at_exit_)
-    g_at_exit_ = new base::AtExitManager;
-
-  // Change the framework bundle to the bundle that contain CrNet framework.
-  // By default the framework bundle is set equal to the main (app) bundle.
-  NSBundle* frameworkBundle = [NSBundle bundleForClass:CrNet.class];
-  base::mac::SetOverrideFrameworkBundle(frameworkBundle);
-#if !BUILDFLAG(USE_PLATFORM_ICU_ALTERNATIVES)
-  CHECK(base::i18n::InitializeICU());
-#endif
-  url::Initialize();
-  base::CommandLine::Init(0, nullptr);
-
-  // Without doing this, StatisticsRecorder::FactoryGet() leaks one histogram
-  // per call after the first for a given name.
-  base::StatisticsRecorder::Initialize();
-
-  // Create a message loop on the UI thread.
-  base::MessageLoop* main_message_loop =
-      new base::MessageLoop(base::MessageLoop::TYPE_UI);
-#pragma unused(main_message_loop)
-  base::MessageLoopForUI::current()->Attach();
-}
-
-void CrNetEnvironment::StartNetLog(base::FilePath::StringType file_name,
-    bool log_bytes) {
-  DCHECK(file_name.length());
-  PostToFileUserBlockingThread(FROM_HERE,
-      base::Bind(&CrNetEnvironment::StartNetLogInternal,
-                 base::Unretained(this), file_name, log_bytes));
-}
-
-void CrNetEnvironment::StartNetLogInternal(
-    base::FilePath::StringType file_name, bool log_bytes) {
-  DCHECK(file_user_blocking_thread_->task_runner()->BelongsToCurrentThread());
-  DCHECK(file_name.length());
-  DCHECK(net_log_);
-
-  if (net_log_observer_)
-    return;
-
-  base::FilePath temp_dir;
-  if (!base::GetTempDir(&temp_dir))
-    return;
-
-  base::FilePath full_path = temp_dir.Append(file_name);
-  base::ScopedFILE file(base::OpenFile(full_path, "w"));
-  if (!file)
-    return;
-
-  net::NetLogCaptureMode capture_mode = log_bytes ?
-      net::NetLogCaptureMode::IncludeSocketBytes() :
-      net::NetLogCaptureMode::Default();
-
-  net_log_observer_.reset(new net::WriteToFileNetLogObserver());
-  net_log_observer_->set_capture_mode(capture_mode);
-  net_log_observer_->StartObserving(net_log_.get(), std::move(file), nullptr,
-                                    nullptr);
-}
-
-void CrNetEnvironment::StopNetLog() {
-  PostToFileUserBlockingThread(FROM_HERE,
-      base::Bind(&CrNetEnvironment::StopNetLogInternal,
-      base::Unretained(this)));
-}
-
-void CrNetEnvironment::StopNetLogInternal() {
-  DCHECK(file_user_blocking_thread_->task_runner()->BelongsToCurrentThread());
-  if (net_log_observer_) {
-    net_log_observer_->StopObserving(nullptr);
-    net_log_observer_.reset();
-  }
-}
-
-void CrNetEnvironment::CloseAllSpdySessions() {
-  PostToNetworkThread(FROM_HERE,
-      base::Bind(&CrNetEnvironment::CloseAllSpdySessionsInternal,
-      base::Unretained(this)));
-}
-
-void CrNetEnvironment::SetRequestFilterBlock(RequestFilterBlock block) {
-  http_protocol_handler_delegate_.reset(
-      new CrNetHttpProtocolHandlerDelegate(main_context_getter_.get(), block));
-  net::HTTPProtocolHandlerDelegate::SetInstance(
-      http_protocol_handler_delegate_.get());
-}
-
-net::HttpNetworkSession* CrNetEnvironment::GetHttpNetworkSession(
-    net::URLRequestContext* context) {
-  DCHECK(context);
-  if (!context->http_transaction_factory())
-    return nullptr;
-
-  return context->http_transaction_factory()->GetSession();
-}
-
-void CrNetEnvironment::CloseAllSpdySessionsInternal() {
-  DCHECK(network_io_thread_->task_runner()->BelongsToCurrentThread());
-
-  net::HttpNetworkSession* http_network_session =
-      GetHttpNetworkSession(GetMainContextGetter()->GetURLRequestContext());
-
-  if (http_network_session) {
-    net::SpdySessionPool *spdy_session_pool =
-        http_network_session->spdy_session_pool();
-    if (spdy_session_pool)
-      spdy_session_pool->CloseCurrentSessions(net::ERR_ABORTED);
-  }
-}
-
-CrNetEnvironment::CrNetEnvironment(const std::string& user_agent,
-                                   bool user_agent_partial)
-    : spdy_enabled_(false),
-      quic_enabled_(false),
-      sdch_enabled_(false),
-      main_context_(new net::URLRequestContext),
-      user_agent_(user_agent),
-      user_agent_partial_(user_agent_partial),
-      net_log_(new net::NetLog) {}
-
-void CrNetEnvironment::Install() {
-  // Threads setup.
-  network_cache_thread_.reset(new base::Thread("Chrome Network Cache Thread"));
-  network_cache_thread_->StartWithOptions(
-      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
-  network_io_thread_.reset(new base::Thread("Chrome Network IO Thread"));
-  network_io_thread_->StartWithOptions(
-      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
-  file_thread_.reset(new base::Thread("Chrome File Thread"));
-  file_thread_->StartWithOptions(
-      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
-  file_user_blocking_thread_.reset(
-      new base::Thread("Chrome File User Blocking Thread"));
-  file_user_blocking_thread_->StartWithOptions(
-      base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
-
-  // The network change notifier must be initialized so that registered
-  // delegates will receive callbacks.
-  network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
-  proxy_config_service_ = net::ProxyService::CreateSystemProxyConfigService(
-      network_io_thread_->task_runner());
-
-  main_context_getter_ = new CrNetURLRequestContextGetter(
-      main_context_.get(), network_io_thread_->task_runner());
-  base::subtle::MemoryBarrier();
-  PostToNetworkThread(FROM_HERE,
-      base::Bind(&CrNetEnvironment::InitializeOnNetworkThread,
-                 base::Unretained(this)));
-
-  SetRequestFilterBlock(nil);
-}
-
-void CrNetEnvironment::InstallIntoSessionConfiguration(
-    NSURLSessionConfiguration* config) {
-  config.protocolClasses = @[ [CRNHTTPProtocolHandler class] ];
-}
-
-CrNetEnvironment::~CrNetEnvironment() {
-  net::HTTPProtocolHandlerDelegate::SetInstance(nullptr);
-}
-
-net::URLRequestContextGetter* CrNetEnvironment::GetMainContextGetter() {
-  return main_context_getter_.get();
-}
-
-void CrNetEnvironment::SetHTTPProtocolHandlerRegistered(bool registered) {
-  if (registered) {
-    // Disable the default cache.
-    [NSURLCache setSharedURLCache:[EmptyNSURLCache emptyNSURLCache]];
-    // Register the chrome http protocol handler to replace the default one.
-    BOOL success =
-        [NSURLProtocol registerClass:[CRNHTTPProtocolHandler class]];
-    DCHECK(success);
-  } else {
-    // Set up an empty default cache, with default size.
-    // TODO(droger): If the NSURLCache is to be used, its size should most
-    // likely be changed. On an iPod2 with iOS4, the default size is 512k.
-    [NSURLCache setSharedURLCache:[[NSURLCache alloc] init]];
-    [NSURLProtocol unregisterClass:[CRNHTTPProtocolHandler class]];
-  }
-}
-
-void CrNetEnvironment::ConfigureSdchOnNetworkThread() {
-  DCHECK(network_io_thread_->task_runner()->BelongsToCurrentThread());
-  net::URLRequestContext* context =
-      main_context_getter_->GetURLRequestContext();
-
-  if (!sdch_enabled_) {
-    DCHECK_EQ(static_cast<net::SdchManager*>(nullptr), context->sdch_manager());
-    return;
-  }
-
-  sdch_manager_.reset(new net::SdchManager());
-  sdch_owner_.reset(new net::SdchOwner(sdch_manager_.get(), context));
-  if (!sdch_pref_store_filename_.empty()) {
-    base::FilePath path(sdch_pref_store_filename_);
-    pref_store_worker_pool_ = file_user_blocking_thread_->task_runner();
-    net_pref_store_ = new JsonPrefStore(path, pref_store_worker_pool_.get(),
-                                        std::unique_ptr<PrefFilter>());
-    net_pref_store_->ReadPrefsAsync(nullptr);
-    sdch_owner_->EnablePersistentStorage(
-        std::unique_ptr<net::SdchOwner::PrefStorage>(
-            new SdchOwnerPrefStorage(net_pref_store_.get())));
-  }
-  context->set_sdch_manager(sdch_manager_.get());
-}
-
-void CrNetEnvironment::InitializeOnNetworkThread() {
-  DCHECK(network_io_thread_->task_runner()->BelongsToCurrentThread());
-  base::FeatureList::InitializeInstance(std::string(), std::string());
-
-  ConfigureSdchOnNetworkThread();
-
-  // Use the framework bundle to search for resources.
-  NSBundle* frameworkBundle = base::mac::FrameworkBundle();
-  NSString* bundlePath =
-      [frameworkBundle pathForResource:@"crnet_resources" ofType:@"bundle"];
-  NSBundle* bundle = [NSBundle bundleWithPath:bundlePath];
-  NSString* acceptableLanguages = NSLocalizedStringWithDefaultValue(
-      @"IDS_ACCEPT_LANGUAGES",
-      @"Localizable",
-      bundle,
-      @"en-US,en",
-      @"These values are copied from Chrome's .xtb files, so the same "
-       "values are used in the |Accept-Language| header. Key name matches "
-       "Chrome's.");
-  if (acceptableLanguages == Nil)
-    acceptableLanguages = @"en-US,en";
-  std::string acceptable_languages =
-      [acceptableLanguages cStringUsingEncoding:NSUTF8StringEncoding];
-  if (user_agent_partial_) {
-    user_agent_ = web::BuildUserAgentFromProduct(user_agent_);
-    user_agent_partial_ = false;
-  }
-  // Set the user agent through NSUserDefaults. This sets it for both
-  // UIWebViews and WKWebViews, and javascript calls to navigator.userAgent
-  // return this value.
-  [[NSUserDefaults standardUserDefaults] registerDefaults:@{
-    @"UserAgent" : [NSString stringWithUTF8String:user_agent_.c_str()]
-  }];
-  main_context_->set_http_user_agent_settings(
-      new net::StaticHttpUserAgentSettings(acceptable_languages, user_agent_));
-
-  main_context_->set_ssl_config_service(new net::SSLConfigServiceDefaults);
-  main_context_->set_transport_security_state(
-      new net::TransportSecurityState());
-  std::unique_ptr<net::MultiLogCTVerifier> ct_verifier =
-      base::MakeUnique<net::MultiLogCTVerifier>();
-  ct_verifier->AddLogs(net::ct::CreateLogVerifiersForKnownLogs());
-  // TODO(mef): Note that the ".release()" calls below are leaking
-  // the objects in question; this should be fixed by having an object
-  // corresponding to URLRequestContextStorage that actually owns those
-  // objects.  See http://crbug.com/523858.
-  main_context_->set_cert_transparency_verifier(ct_verifier.release());
-  main_context_->set_ct_policy_enforcer(new net::CTPolicyEnforcer());
-  http_server_properties_.reset(new net::HttpServerPropertiesImpl());
-  main_context_->set_http_server_properties(http_server_properties_.get());
-  main_context_->set_host_resolver(
-      net::HostResolver::CreateDefaultResolver(nullptr).release());
-  main_context_->set_cert_verifier(
-      net::CertVerifier::CreateDefault().release());
-  main_context_->set_http_auth_handler_factory(
-      net::HttpAuthHandlerRegistryFactory::CreateDefault(
-          main_context_->host_resolver())
-          .release());
-  main_context_->set_proxy_service(
-      net::ProxyService::CreateUsingSystemProxyResolver(
-          std::move(proxy_config_service_), nullptr)
-          .release());
-
-  // Cache
-  NSArray* dirs = NSSearchPathForDirectoriesInDomains(NSCachesDirectory,
-                                                      NSUserDomainMask,
-                                                      YES);
-  base::FilePath cache_path =
-      base::mac::NSStringToFilePath([dirs objectAtIndex:0]);
-  cache_path = cache_path.Append(FILE_PATH_LITERAL("crnet"));
-  std::unique_ptr<net::HttpCache::DefaultBackend> main_backend(
-      new net::HttpCache::DefaultBackend(net::DISK_CACHE,
-                                         net::CACHE_BACKEND_DEFAULT, cache_path,
-                                         0,  // Default cache size.
-                                         network_cache_thread_->task_runner()));
-
-  net::HttpNetworkSession::Params session_params;
-  session_params.enable_http2 = spdy_enabled();
-  session_params.enable_quic = quic_enabled();
-
-  net::HttpNetworkSession::Context session_context;
-  session_context.host_resolver = main_context_->host_resolver();
-  session_context.cert_verifier = main_context_->cert_verifier();
-  session_context.cert_transparency_verifier =
-      main_context_->cert_transparency_verifier();
-  session_context.ct_policy_enforcer = main_context_->ct_policy_enforcer();
-  session_context.channel_id_service = main_context_->channel_id_service();
-  session_context.transport_security_state =
-      main_context_->transport_security_state();
-  session_context.proxy_service = main_context_->proxy_service();
-  session_context.ssl_config_service = main_context_->ssl_config_service();
-  session_context.http_auth_handler_factory =
-      main_context_->http_auth_handler_factory();
-  session_context.http_server_properties =
-      main_context_->http_server_properties();
-  session_context.net_log = main_context_->net_log();
-
-  if (!session_context.channel_id_service) {
-    // The main context may not have a ChannelIDService, since it is lazily
-    // constructed. If not, build an ephemeral ChannelIDService with no backing
-    // disk store.
-    // TODO(ellyjones): support persisting ChannelID.
-    session_context.channel_id_service =
-        new net::ChannelIDService(new net::DefaultChannelIDStore(NULL));
-  }
-
-  // TODO(mmenke):  These really shouldn't be leaked.
-  //                See https://crbug.com/523858.
-  net::HttpNetworkSession* http_network_session =
-      new net::HttpNetworkSession(session_params, session_context);
-  net::HttpCache* main_cache =
-      new net::HttpCache(http_network_session, std::move(main_backend),
-                         true /* set_up_quic_server_info */);
-  main_context_->set_http_transaction_factory(main_cache);
-
-  // Cookies
-  [[NSHTTPCookieStorage sharedHTTPCookieStorage]
-      setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
-  cookie_store_ = base::MakeUnique<net::CookieStoreIOS>(
-      [NSHTTPCookieStorage sharedHTTPCookieStorage]);
-  main_context_->set_cookie_store(cookie_store_.get());
-
-  net::URLRequestJobFactoryImpl* job_factory =
-      new net::URLRequestJobFactoryImpl;
-  job_factory->SetProtocolHandler(
-      "data", base::WrapUnique(new net::DataProtocolHandler));
-#if !BUILDFLAG(DISABLE_FILE_SUPPORT)
-  job_factory->SetProtocolHandler(
-      "file",
-      base::MakeUnique<net::FileProtocolHandler>(file_thread_->task_runner()));
-#endif   // !BUILDFLAG(DISABLE_FILE_SUPPORT)
-  main_context_->set_job_factory(job_factory);
-
-  main_context_->set_net_log(net_log_.get());
-}
-
-std::string CrNetEnvironment::user_agent() {
-  const net::HttpUserAgentSettings* user_agent_settings =
-      main_context_->http_user_agent_settings();
-  if (!user_agent_settings) {
-    return nullptr;
-  }
-
-  return user_agent_settings->GetUserAgent();
-}
-
-void CrNetEnvironment::ClearCache(ClearCacheCallback callback) {
-  PostToNetworkThread(
-      FROM_HERE, base::Bind(&net::ClearHttpCache, main_context_getter_,
-                            network_io_thread_->task_runner(), base::Time(),
-                            base::Time::Max(), base::BindBlockArc(callback)));
-}
diff --git a/ios/crnet/sdch_owner_pref_storage.cc b/ios/crnet/sdch_owner_pref_storage.cc
deleted file mode 100644
index 292eaa24..0000000
--- a/ios/crnet/sdch_owner_pref_storage.cc
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ios/crnet/sdch_owner_pref_storage.h"
-
-#include "base/values.h"
-#include "components/prefs/persistent_pref_store.h"
-
-namespace {
-
-static const char kStorageKey[] = "SDCH";
-
-}  // namespace
-
-SdchOwnerPrefStorage::SdchOwnerPrefStorage(PersistentPrefStore* storage)
-    : storage_(storage),
-      storage_key_(kStorageKey),
-      init_observer_(nullptr) {
-}
-
-SdchOwnerPrefStorage::~SdchOwnerPrefStorage() {
-  if (init_observer_)
-    storage_->RemoveObserver(this);
-}
-
-net::SdchOwner::PrefStorage::ReadError
-SdchOwnerPrefStorage::GetReadError() const {
-  PersistentPrefStore::PrefReadError error = storage_->GetReadError();
-
-  DCHECK_NE(error,
-            PersistentPrefStore::PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE);
-  DCHECK_NE(error, PersistentPrefStore::PREF_READ_ERROR_MAX_ENUM);
-
-  switch (error) {
-    case PersistentPrefStore::PREF_READ_ERROR_NONE:
-      return PERSISTENCE_FAILURE_NONE;
-
-    case PersistentPrefStore::PREF_READ_ERROR_NO_FILE:
-      return PERSISTENCE_FAILURE_REASON_NO_FILE;
-
-    case PersistentPrefStore::PREF_READ_ERROR_JSON_PARSE:
-    case PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE:
-    case PersistentPrefStore::PREF_READ_ERROR_FILE_OTHER:
-    case PersistentPrefStore::PREF_READ_ERROR_FILE_LOCKED:
-    case PersistentPrefStore::PREF_READ_ERROR_JSON_REPEAT:
-      return PERSISTENCE_FAILURE_REASON_READ_FAILED;
-
-    case PersistentPrefStore::PREF_READ_ERROR_ACCESS_DENIED:
-    case PersistentPrefStore::PREF_READ_ERROR_FILE_NOT_SPECIFIED:
-    case PersistentPrefStore::PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE:
-    case PersistentPrefStore::PREF_READ_ERROR_MAX_ENUM:
-    default:
-      // We don't expect these other failures given our usage of prefs.
-      NOTREACHED();
-      return PERSISTENCE_FAILURE_REASON_OTHER;
-  }
-}
-
-bool SdchOwnerPrefStorage::GetValue(
-      const base::DictionaryValue** result) const {
-  const base::Value* result_value = nullptr;
-  if (!storage_->GetValue(storage_key_, &result_value))
-    return false;
-  return result_value->GetAsDictionary(result);
-}
-
-bool SdchOwnerPrefStorage::GetMutableValue(base::DictionaryValue** result) {
-  base::Value* result_value = nullptr;
-  if (!storage_->GetMutableValue(storage_key_, &result_value))
-    return false;
-  return result_value->GetAsDictionary(result);
-}
-
-void SdchOwnerPrefStorage::SetValue(
-    std::unique_ptr<base::DictionaryValue> value) {
-  storage_->SetValue(storage_key_, std::move(value),
-                     WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
-}
-
-void SdchOwnerPrefStorage::ReportValueChanged() {
-  storage_->ReportValueChanged(storage_key_,
-                               WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
-}
-
-bool SdchOwnerPrefStorage::IsInitializationComplete() {
-  return storage_->IsInitializationComplete();
-}
-
-void SdchOwnerPrefStorage::StartObservingInit(net::SdchOwner* observer) {
-  DCHECK(!init_observer_);
-  init_observer_ = observer;
-  storage_->AddObserver(this);
-}
-
-void SdchOwnerPrefStorage::StopObservingInit() {
-  DCHECK(init_observer_);
-  init_observer_ = nullptr;
-  storage_->RemoveObserver(this);
-}
-
-void SdchOwnerPrefStorage::OnPrefValueChanged(const std::string& key) {
-}
-
-void SdchOwnerPrefStorage::OnInitializationCompleted(bool succeeded) {
-  DCHECK(init_observer_);
-  init_observer_->OnPrefStorageInitializationComplete(succeeded);
-}
diff --git a/ios/crnet/sdch_owner_pref_storage.h b/ios/crnet/sdch_owner_pref_storage.h
deleted file mode 100644
index 5ecaf1e..0000000
--- a/ios/crnet/sdch_owner_pref_storage.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IOS_CRNET_SDCH_OWNER_PREF_STORAGE_H_
-#define IOS_CRNET_SDCH_OWNER_PREF_STORAGE_H_
-
-#include <memory>
-
-#include "base/macros.h"
-#include "components/prefs/pref_store.h"
-#include "net/sdch/sdch_owner.h"
-
-class PersistentPrefStore;
-
-// Provides an implementation of SdchOwner::PrefStorage that maps to
-// Chrome's preferences system.
-class SdchOwnerPrefStorage
-    : public net::SdchOwner::PrefStorage,
-      public PrefStore::Observer {
- public:
-  // The storage must outlive this class.
-  explicit SdchOwnerPrefStorage(PersistentPrefStore* storage);
-  ~SdchOwnerPrefStorage() override;
-
-  ReadError GetReadError() const override;
-  bool GetValue(const base::DictionaryValue** result) const override;
-  bool GetMutableValue(base::DictionaryValue** result) override;
-  void SetValue(std::unique_ptr<base::DictionaryValue> value) override;
-  void ReportValueChanged() override;
-  bool IsInitializationComplete() override;
-  void StartObservingInit(net::SdchOwner* observer) override;
-  void StopObservingInit() override;
-
- private:
-  // PrefStore::Observer implementation.
-  void OnPrefValueChanged(const std::string& key) override;
-  void OnInitializationCompleted(bool succeeded) override;
-
-  PersistentPrefStore* storage_;  // Non-owning.
-  const std::string storage_key_;
-
-  net::SdchOwner* init_observer_;  // Non-owning.
-
-  DISALLOW_COPY_AND_ASSIGN(SdchOwnerPrefStorage);
-};
-
-#endif  // IOS_CRNET_SDCH_OWNER_PREF_STORAGE_H_
diff --git a/ios/crnet/test/BUILD.gn b/ios/crnet/test/BUILD.gn
deleted file mode 100644
index f96fe82..0000000
--- a/ios/crnet/test/BUILD.gn
+++ /dev/null
@@ -1,25 +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.
-
-import("//build/config/ios/rules.gni")
-import("//testing/test.gni")
-
-test("crnet_test") {
-  testonly = true
-  sources = [
-    "crnet_http_tests.mm",
-    "crnet_test_runner.mm",
-  ]
-
-  deps = [
-    "//base",
-    "//base:i18n",
-    "//ios/crnet:crnet_framework+link",
-    "//ios/third_party/gcdwebserver",
-    "//net:test_support",
-    "//third_party/icu",
-  ]
-
-  bundle_deps = [ "//ios/crnet:crnet_framework+bundle" ]
-}
diff --git a/ios/crnet/test/crnet_http_tests.mm b/ios/crnet/test/crnet_http_tests.mm
deleted file mode 100644
index 7ab9b39..0000000
--- a/ios/crnet/test/crnet_http_tests.mm
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import <Foundation/Foundation.h>
-#include <stdint.h>
-
-#import <CrNet/CrNet.h>
-
-#include "base/logging.h"
-#include "base/mac/scoped_nsobject.h"
-#include "base/strings/sys_string_conversions.h"
-#import "ios/third_party/gcdwebserver/src/GCDWebServer/Core/GCDWebServer.h"
-#import "ios/third_party/gcdwebserver/src/GCDWebServer/Responses/GCDWebServerDataResponse.h"
-#include "net/base/mac/url_conversions.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/gtest_mac.h"
-#include "url/gurl.h"
-
-@interface TestDelegate : NSObject<NSURLSessionDataDelegate,
-                                   NSURLSessionDelegate,
-                                   NSURLSessionTaskDelegate>
-
-// Completion semaphore for this TestDelegate. When the request this delegate is
-// attached to finishes (either successfully or with an error), this delegate
-// signals this semaphore.
-@property(assign, nonatomic) dispatch_semaphore_t semaphore;
-
-// Total count of bytes received by the request this delegate is attached to.
-@property(nonatomic) unsigned long receivedBytes;
-
-// Error the request this delegate is attached to failed with, if any.
-@property(retain, nonatomic) NSError* error;
-
-@end
-
-@implementation TestDelegate
-@synthesize semaphore = _semaphore;
-@synthesize receivedBytes = _receivedBytes;
-@synthesize error = _error;
-
-- (id)init {
-  if (self = [super init]) {
-    _semaphore = dispatch_semaphore_create(0);
-  }
-  return self;
-}
-
-- (void)dealloc {
-  dispatch_release(_semaphore);
-  [_error release];
-  _error = nil;
-  [super dealloc];
-}
-
-- (void)URLSession:(NSURLSession*)session
-    didBecomeInvalidWithError:(NSError*)error {
-}
-
-- (void)URLSession:(NSURLSession*)session
-                    task:(NSURLSessionTask*)task
-    didCompleteWithError:(NSError*)error {
-  [self setError:error];
-  dispatch_semaphore_signal(_semaphore);
-}
-
-- (void)URLSession:(NSURLSession*)session
-                   task:(NSURLSessionTask*)task
-    didReceiveChallenge:(NSURLAuthenticationChallenge*)challenge
-      completionHandler:
-          (void (^)(NSURLSessionAuthChallengeDisposition disp,
-                    NSURLCredential* credential))completionHandler {
-  completionHandler(NSURLSessionAuthChallengeUseCredential, nil);
-}
-
-- (void)URLSession:(NSURLSession*)session
-              dataTask:(NSURLSessionDataTask*)dataTask
-    didReceiveResponse:(NSURLResponse*)response
-     completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))
-                           completionHandler {
-  completionHandler(NSURLSessionResponseAllow);
-}
-
-- (void)URLSession:(NSURLSession*)session
-          dataTask:(NSURLSessionDataTask*)dataTask
-    didReceiveData:(NSData*)data {
-  _receivedBytes += (unsigned long)data.length;
-}
-
-- (void)URLSession:(NSURLSession*)session
-             dataTask:(NSURLSessionDataTask*)dataTask
-    willCacheResponse:(NSCachedURLResponse*)proposedResponse
-    completionHandler:
-        (void (^)(NSCachedURLResponse* cachedResponse))completionHandler {
-  completionHandler(proposedResponse);
-}
-
-@end
-
-// base::TimeDelta would normally be ideal for this but it does not support
-// nanosecond resolution.
-static const int64_t ns_in_second = 1000000000LL;
-const char kUserAgent[] = "CrNetTest/1.0.0.0";
-
-class HttpTest : public ::testing::Test {
- protected:
-  HttpTest() {}
-  ~HttpTest() override {}
-
-  void SetUp() override {
-    [CrNet setUserAgent:base::SysUTF8ToNSString(kUserAgent) partial:NO];
-    [CrNet install];
-    NSURLSessionConfiguration* config =
-        [NSURLSessionConfiguration ephemeralSessionConfiguration];
-    [CrNet installIntoSessionConfiguration:config];
-    delegate_.reset([[TestDelegate alloc] init]);
-    NSURLSession* session = [NSURLSession sessionWithConfiguration:config
-                                                          delegate:delegate_
-                                                     delegateQueue:nil];
-    // Take a reference to the session and store it so it doesn't get
-    // deallocated until this object does.
-    session_.reset([session retain]);
-    web_server_.reset([[GCDWebServer alloc] init]);
-  }
-
-  void TearDown() override {
-    [CrNet uninstall];
-    [web_server_ stop];
-  }
-
-  // Starts a GCDWebServer instance on localhost port 8080, and remembers the
-  // root URL for later; tests can use GetURL() to produce a URL referring to a
-  // specific resource under the root URL.
-  void StartWebServer() {
-    [web_server_ startWithPort:8080 bonjourName:nil];
-    server_root_ = net::GURLWithNSURL([web_server_ serverURL]);
-  }
-
-  // Registers a fixed response |text| to be returned to requests for |path|,
-  // which is relative to |server_root_|.
-  void RegisterPathText(const std::string& path, const std::string& text) {
-    NSString* nspath = base::SysUTF8ToNSString(path);
-    NSData* data = [NSData dataWithBytes:text.c_str() length:text.length()];
-    [web_server_ addGETHandlerForPath:nspath
-                          staticData:data
-                         contentType:@"text/plain"
-                            cacheAge:30];
-  }
-
-  void RegisterPathHandler(const std::string& path,
-                           GCDWebServerProcessBlock handler) {
-    NSString* nspath = base::SysUTF8ToNSString(path);
-    [web_server_ addHandlerForMethod:@"GET"
-                                path:nspath
-                        requestClass:NSClassFromString(@"GCDWebServerRequest")
-                        processBlock:handler];
-  }
-
-  // Launches the supplied |task| and blocks until it completes, with a timeout
-  // of 1 second.
-  void StartDataTaskAndWaitForCompletion(NSURLSessionDataTask* task) {
-    [task resume];
-    int64_t deadline_ns = 1 * ns_in_second;
-    dispatch_semaphore_wait([delegate_ semaphore],
-                            dispatch_time(DISPATCH_TIME_NOW, deadline_ns));
-  }
-
-  // Returns a URL to refer to the resource named |path| served by the test
-  // server. If |path| starts with a /, the leading / will be stripped.
-  GURL GetURL(const std::string& path) {
-    std::string real_path = path[0] == '/' ? path.substr(1) : path;
-    return server_root_.Resolve(real_path);
-  }
-
-  // Some convenience functions for working with GCDWebServerRequest and
-  // GCDWebServerResponse.
-
-  // Returns true if the value for the request header |header| is not nil and
-  // contains the string |target|.
-  bool HeaderValueContains(GCDWebServerRequest* request,
-                           const std::string& header,
-                           const std::string& target) {
-    NSString* key = base::SysUTF8ToNSString(header);
-    NSString* needle = base::SysUTF8ToNSString(target);
-    NSString* haystack = request.headers[key];
-    if (!haystack)
-      return false;
-    return [haystack rangeOfString:needle].location != NSNotFound;
-  }
-
-  base::scoped_nsobject<NSURLSession> session_;
-  base::scoped_nsobject<TestDelegate> delegate_;
-
- private:
-  base::scoped_nsobject<GCDWebServer> web_server_;
-  GURL server_root_;
-};
-
-TEST_F(HttpTest, NSURLSessionReceivesData) {
-  const char kPath[] = "/foo";
-  const char kData[] = "foobar";
-  RegisterPathText(kPath, kData);
-  StartWebServer();
-
-  NSURL* url = net::NSURLWithGURL(GetURL(kPath));
-  NSURLSessionDataTask* task = [session_ dataTaskWithURL:url];
-  StartDataTaskAndWaitForCompletion(task);
-  EXPECT_EQ(nil, [delegate_ error]);
-  EXPECT_EQ(strlen(kData), [delegate_ receivedBytes]);
-}
-
-TEST_F(HttpTest, SdchDisabledByDefault) {
-  const char kPath[] = "/sdchtest";
-  RegisterPathHandler(kPath,
-      ^GCDWebServerResponse* (GCDWebServerRequest* req) {
-        EXPECT_FALSE(HeaderValueContains(req, "Accept-Encoding", "sdch"));
-        return [GCDWebServerDataResponse responseWithText:@"woot!"];
-      });
-  StartWebServer();
-  NSURL* url = net::NSURLWithGURL(GetURL(kPath));
-  NSURLSessionDataTask* task = [session_ dataTaskWithURL:url];
-  StartDataTaskAndWaitForCompletion(task);
-  EXPECT_EQ(nil, [delegate_ error]);
-  EXPECT_TRUE([delegate_ receivedBytes]);
-}
-
-TEST_F(HttpTest, SetUserAgentIsExact) {
-  const char kPath[] = "/uatest";
-  RegisterPathHandler(kPath, ^GCDWebServerResponse*(GCDWebServerRequest* req) {
-    EXPECT_STREQ(kUserAgent,
-                 [[req.headers valueForKey:@"User-Agent"] UTF8String]);
-    return [GCDWebServerDataResponse responseWithText:@"yay!"];
-  });
-  StartWebServer();
-  NSURL* url = net::NSURLWithGURL(GetURL(kPath));
-  NSURLSessionDataTask* task = [session_ dataTaskWithURL:url];
-  StartDataTaskAndWaitForCompletion(task);
-  EXPECT_EQ(nil, [delegate_ error]);
-  EXPECT_TRUE([delegate_ receivedBytes]);
-}
-
-// TODO(ellyjones): There needs to be a test that enabling SDCH works, but
-// because CrNet is static and 'uninstall' only disables it, there is no way to
-// have an individual test enable or disable SDCH.
-// Probably there is a way to get gtest tests to run in a separate process, but
-// I'm not sure what it is.
diff --git a/ios/crnet/test/crnet_test_runner.mm b/ios/crnet/test/crnet_test_runner.mm
deleted file mode 100644
index 869f738a..0000000
--- a/ios/crnet/test/crnet_test_runner.mm
+++ /dev/null
@@ -1,11 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "testing/gtest_mac.h"
-
-int main(int argc, char* argv[]) {
-  ::testing::InitGoogleTest(&argc, argv);
-  return RUN_ALL_TESTS();
-}
diff --git a/ios/web/payments/payment_request.cc b/ios/web/payments/payment_request.cc
index d0aef08..73657d0 100644
--- a/ios/web/payments/payment_request.cc
+++ b/ios/web/payments/payment_request.cc
@@ -189,16 +189,18 @@
   return !(*this == other);
 }
 
-bool PaymentDetails::FromDictionaryValue(const base::DictionaryValue& value) {
+bool PaymentDetails::FromDictionaryValue(const base::DictionaryValue& value,
+                                         bool requires_total) {
   this->display_items.clear();
   this->shipping_options.clear();
   this->modifiers.clear();
 
   const base::DictionaryValue* total_dict = nullptr;
-  if (!value.GetDictionary(kPaymentDetailsTotal, &total_dict)) {
+  if (!value.GetDictionary(kPaymentDetailsTotal, &total_dict) &&
+      requires_total) {
     return false;
   }
-  if (!this->total.FromDictionaryValue(*total_dict)) {
+  if (total_dict && !this->total.FromDictionaryValue(*total_dict)) {
     return false;
   }
 
@@ -324,7 +326,8 @@
   // Parse the payment details.
   const base::DictionaryValue* payment_details_dict = nullptr;
   if (!value.GetDictionary(kPaymentRequestDetails, &payment_details_dict) ||
-      !this->details.FromDictionaryValue(*payment_details_dict)) {
+      !this->details.FromDictionaryValue(*payment_details_dict,
+                                         /*requires_total=*/true)) {
     return false;
   }
 
diff --git a/ios/web/payments/payment_request_unittest.cc b/ios/web/payments/payment_request_unittest.cc
index 1552ff41..45e3131 100644
--- a/ios/web/payments/payment_request_unittest.cc
+++ b/ios/web/payments/payment_request_unittest.cc
@@ -96,6 +96,55 @@
   EXPECT_FALSE(actual.FromDictionaryValue(item_dict));
 }
 
+// Tests the success case when populating a PaymentDetails from a dictionary.
+TEST(PaymentRequestTest, PaymentDetailsFromDictionaryValueSuccess) {
+  PaymentDetails expected;
+  expected.error = base::ASCIIToUTF16("Error in details");
+
+  base::DictionaryValue details_dict;
+  details_dict.SetString("error", "Error in details");
+  PaymentDetails actual;
+  EXPECT_TRUE(
+      actual.FromDictionaryValue(details_dict, /*requires_total=*/false));
+  EXPECT_EQ(expected, actual);
+
+  expected.total.label = base::ASCIIToUTF16("TOTAL");
+  expected.total.amount.currency = base::ASCIIToUTF16("GBP");
+  expected.total.amount.value = base::ASCIIToUTF16("6.66");
+
+  std::unique_ptr<base::DictionaryValue> total_dict(new base::DictionaryValue);
+  total_dict->SetString("label", "TOTAL");
+  std::unique_ptr<base::DictionaryValue> amount_dict(new base::DictionaryValue);
+  amount_dict->SetString("currency", "GBP");
+  amount_dict->SetString("value", "6.66");
+  total_dict->Set("amount", std::move(amount_dict));
+  details_dict.Set("total", std::move(total_dict));
+
+  EXPECT_TRUE(
+      actual.FromDictionaryValue(details_dict, /*requires_total=*/false));
+  EXPECT_EQ(expected, actual);
+
+  EXPECT_TRUE(
+      actual.FromDictionaryValue(details_dict, /*requires_total=*/true));
+  EXPECT_EQ(expected, actual);
+}
+
+// Tests the failure case when populating a PaymentDetails from a dictionary.
+TEST(PaymentRequestTest, PaymentDetailsFromDictionaryValueFailure) {
+  PaymentDetails expected;
+  expected.total.label = base::ASCIIToUTF16("TOTAL");
+  expected.total.amount.currency = base::ASCIIToUTF16("GBP");
+  expected.total.amount.value = base::ASCIIToUTF16("6.66");
+  expected.error = base::ASCIIToUTF16("Error in details");
+
+  base::DictionaryValue details_dict;
+  details_dict.SetString("error", "Error in details");
+
+  PaymentDetails actual;
+  EXPECT_FALSE(
+      actual.FromDictionaryValue(details_dict, /*requires_total=*/true));
+}
+
 // Tests the success case when populating a PaymentShippingOption from a
 // dictionary.
 TEST(PaymentRequestTest, PaymentShippingOptionFromDictionaryValueSuccess) {
diff --git a/ios/web/public/payments/payment_request.h b/ios/web/public/payments/payment_request.h
index 4952bd5..5eee723 100644
--- a/ios/web/public/payments/payment_request.h
+++ b/ios/web/public/payments/payment_request.h
@@ -147,8 +147,10 @@
   bool operator!=(const PaymentDetails& other) const;
 
   // Populates the properties of this PaymentDetails from |value|. Returns true
-  // if the required values are present.
-  bool FromDictionaryValue(const base::DictionaryValue& value);
+  // if the required values are present. If |requires_total| is true, the total
+  // property has to be present.
+  bool FromDictionaryValue(const base::DictionaryValue& value,
+                           bool requires_total);
 
   // The total amount of the payment request.
   PaymentItem total;
diff --git a/ios/web/public/web_kit_constants.h b/ios/web/public/web_kit_constants.h
index 2577fc05d..9ce201a 100644
--- a/ios/web/public/web_kit_constants.h
+++ b/ios/web/public/web_kit_constants.h
@@ -19,7 +19,9 @@
 // Can not change location URL.
 const long kWebKitErrorCannotShowUrl = 101;
 
-// Frame load was interrupted by a policy change.
+// Frame load was interrupted by a policy change (f.e. by rejecting the load in
+// decidePolicyForNavigationAction: or decidePolicyForNavigationResponse:
+// WKNavigationDelegate callback).
 const long kWebKitErrorFrameLoadInterruptedByPolicyChange = 102;
 
 // Undocumented iOS-specific WebKit error.
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index e567d02..40a5fd65 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -3156,11 +3156,20 @@
   if ([self shouldCancelLoadForCancelledError:error]) {
     [self loadCancelled];
     [[self sessionController] discardNonCommittedItems];
+    // If discarding the non-committed entries results in native content URL,
+    // reload it in its native view.
+    if (!self.nativeController) {
+      GURL lastCommittedURL = self.webState->GetLastCommittedURL();
+      if ([self shouldLoadURLInNativeView:lastCommittedURL]) {
+        [self loadCurrentURLInNativeView];
+      }
+    }
   }
 }
 
 - (BOOL)shouldCancelLoadForCancelledError:(NSError*)error {
-  DCHECK_EQ(error.code, NSURLErrorCancelled);
+  DCHECK(error.code == NSURLErrorCancelled ||
+         error.code == web::kWebKitErrorFrameLoadInterruptedByPolicyChange);
   // Do not cancel the load if it is for an app specific URL, as such errors
   // are produced during the app specific URL load process.
   const GURL errorURL =
@@ -4502,7 +4511,7 @@
   // Handle load cancellation for directly cancelled navigations without
   // handling their potential errors. Otherwise, handle the error.
   if ([_pendingNavigationInfo cancelled]) {
-    [self loadCancelled];
+    [self handleCancelledError:error];
   } else {
     error = WKWebViewErrorWithSource(error, PROVISIONAL_LOAD);
 
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn
index a17386d..cd97490 100644
--- a/ios/web_view/BUILD.gn
+++ b/ios/web_view/BUILD.gn
@@ -144,30 +144,6 @@
   ]
 }
 
-# Same framework as ChromeWebView above, but also exposes CrNet.
-ios_framework_bundle("crnet_web_view_combined") {
-  output_name = "CrNetChromeWebView"
-  info_plist = "Info.plist"
-
-  public_headers = ios_web_view_public_headers
-  public_headers += [ "../crnet/CrNet.h" ]
-
-  public = [
-    "public/ChromeWebView.h",
-  ]
-
-  sources = ios_web_view_sources
-  sources += [ "../crnet/CrNet.h" ]
-
-  deps = ios_web_view_deps
-  deps += [ "//ios/crnet:crnet_sources" ]
-
-  configs += [
-    ":config",
-    "//build/config/compiler:enable_arc",
-  ]
-}
-
 # Same framework as ChromeWebView above, but also exposes Cronet.
 ios_framework_bundle("cronet_web_view_combined") {
   output_name = "CronetChromeWebView"
diff --git a/ios/web_view/internal/web_view_web_main_delegate.mm b/ios/web_view/internal/web_view_web_main_delegate.mm
index 3d24bbe8..40b0be9 100644
--- a/ios/web_view/internal/web_view_web_main_delegate.mm
+++ b/ios/web_view/internal/web_view_web_main_delegate.mm
@@ -5,7 +5,7 @@
 #import "ios/web_view/internal/web_view_web_main_delegate.h"
 
 #import "base/mac/bundle_locations.h"
-#import "ios/web_view/public/cwv_web_view.h"
+#import "ios/web_view/public/cwv_html_element.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
 #error "This file requires ARC support."
@@ -18,8 +18,11 @@
 WebViewWebMainDelegate::~WebViewWebMainDelegate() = default;
 
 void WebViewWebMainDelegate::BasicStartupComplete() {
+  // Use CWVHTMLElement instead of CWVWebView and CWVWebViewConfiguration
+  // because the latter two classes' +intialize calls in to this method and may
+  // cause a deadlock.
   base::mac::SetOverrideFrameworkBundle(
-      [NSBundle bundleForClass:[CWVWebView class]]);
+      [NSBundle bundleForClass:[CWVHTMLElement class]]);
 }
 
 }  // namespace ios_web_view
diff --git a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc
index f68412b..5937cc1c 100644
--- a/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc
+++ b/media/cdm/ppapi/external_clear_key/clear_key_cdm.cc
@@ -433,9 +433,6 @@
 
 void ClearKeyCdm::OnUpdateSuccess(uint32_t promise_id,
                                   const std::string& session_id) {
-  // Resolve the promise first.
-  OnPromiseResolved(promise_id);
-
   // Now create the expiration changed event.
   cdm::Time expiration = 0.0;  // Never expires.
 
@@ -451,6 +448,9 @@
   }
 
   host_->OnExpirationChange(session_id.data(), session_id.length(), expiration);
+
+  // Resolve the promise.
+  OnPromiseResolved(promise_id);
 }
 
 void ClearKeyCdm::CloseSession(uint32_t promise_id,
diff --git a/media/filters/PRESUBMIT.py b/media/filters/PRESUBMIT.py
new file mode 100644
index 0000000..5260d504be
--- /dev/null
+++ b/media/filters/PRESUBMIT.py
@@ -0,0 +1,28 @@
+# Copyright (c) 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.
+
+"""Top-level presubmit script for media/filters/.
+
+See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
+for more details about the presubmit API built into depot_tools.
+"""
+
+def PostUploadHook(cl, change, output_api):
+  """git cl upload will call this hook after the issue is created/modified.
+
+  This hook modifies the CL description in order to run extra GPU
+  tests (in particular, the WebGL 2.0 conformance tests) in addition
+  to the regular CQ try bots. This test suite is too large to run
+  against all Chromium commits, but should be run against changes
+  likely to affect these tests.
+  """
+  return output_api.EnsureCQIncludeTrybotsAreAdded(
+    cl,
+    [
+      'master.tryserver.chromium.linux:linux_optional_gpu_tests_rel',
+      'master.tryserver.chromium.mac:mac_optional_gpu_tests_rel',
+      'master.tryserver.chromium.win:win_optional_gpu_tests_rel',
+      'master.tryserver.chromium.android:android_optional_gpu_tests_rel',
+    ],
+    'Automatically added optional GPU tests to run on CQ.')
diff --git a/media/gpu/dxva_picture_buffer_win.cc b/media/gpu/dxva_picture_buffer_win.cc
index dcd8e330..d7df906d 100644
--- a/media/gpu/dxva_picture_buffer_win.cc
+++ b/media/gpu/dxva_picture_buffer_win.cc
@@ -530,7 +530,7 @@
   result = eglStreamConsumerAcquireKHR(egl_display, stream_);
   RETURN_ON_FAILURE(result, "Could not post acquire stream", false);
   gl::GLImageDXGI* gl_image_dxgi =
-      static_cast<gl::GLImageDXGI*>(gl_image_.get());
+      gl::GLImageDXGI::FromGLImage(gl_image_.get());
   DCHECK(gl_image_dxgi);
 
   gl_image_dxgi->SetTexture(dx11_decoding_texture_, subresource);
@@ -646,13 +646,14 @@
   DCHECK(decoder->d3d11_processor_);
   DCHECK(decoder->enumerator_);
 
-  gl::CopyingGLImageDXGI* gl_image_dxgi =
-      static_cast<gl::CopyingGLImageDXGI*>(gl_image_.get());
+  gl::GLImageDXGI* gl_image_dxgi =
+      gl::GLImageDXGI::FromGLImage(gl_image_.get());
   DCHECK(gl_image_dxgi);
 
   gl_image_dxgi->SetTexture(dx11_decoding_texture_, subresource);
-  return gl_image_dxgi->InitializeVideoProcessor(decoder->d3d11_processor_,
-                                                 decoder->enumerator_);
+  return static_cast<gl::CopyingGLImageDXGI*>(gl_image_dxgi)
+      ->InitializeVideoProcessor(decoder->d3d11_processor_,
+                                 decoder->enumerator_);
 }
 
 bool EGLStreamDelayedCopyPictureBuffer::AllowOverlay() const {
@@ -801,7 +802,7 @@
   result = eglStreamConsumerAcquireKHR(egl_display, stream_);
   RETURN_ON_FAILURE(result, "Could not post acquire stream", false);
   gl::GLImageDXGI* gl_image_dxgi =
-      static_cast<gl::GLImageDXGI*>(gl_image_.get());
+      gl::GLImageDXGI::FromGLImage(gl_image_.get());
   DCHECK(gl_image_dxgi);
 
   gl_image_dxgi->SetTexture(angle_copy_texture_, 0);
diff --git a/media/mojo/clients/mojo_decryptor.cc b/media/mojo/clients/mojo_decryptor.cc
index 9297175..7baecf4c 100644
--- a/media/mojo/clients/mojo_decryptor.cc
+++ b/media/mojo/clients/mojo_decryptor.cc
@@ -224,7 +224,7 @@
                                    Status status,
                                    const scoped_refptr<VideoFrame>& video_frame,
                                    mojom::FrameResourceReleaserPtr releaser) {
-  DVLOG_IF(1, status != kSuccess) << __func__ << "(" << status << ")";
+  DVLOG_IF(1, status != kSuccess) << __func__ << ": status = " << status;
   DVLOG_IF(3, status == kSuccess) << __func__;
   DCHECK(thread_checker_.CalledOnValidThread());
 
diff --git a/media/mojo/services/mojo_cdm_service.cc b/media/mojo/services/mojo_cdm_service.cc
index 98257c09..e7f9787 100644
--- a/media/mojo/services/mojo_cdm_service.cc
+++ b/media/mojo/services/mojo_cdm_service.cc
@@ -176,7 +176,7 @@
                                          bool has_additional_usable_key,
                                          CdmKeysInfo keys_info) {
   DVLOG(2) << __func__
-           << " has_additional_usable_key=" << has_additional_usable_key;
+           << " has_additional_usable_key = " << has_additional_usable_key;
 
   std::vector<mojom::CdmKeyInformationPtr> keys_data;
   for (auto& key : keys_info)
@@ -187,7 +187,7 @@
 
 void MojoCdmService::OnSessionExpirationUpdate(const std::string& session_id,
                                                base::Time new_expiry_time_sec) {
-  DVLOG(2) << __func__ << " expiry=" << new_expiry_time_sec;
+  DVLOG(2) << __func__ << " expiry = " << new_expiry_time_sec;
   client_->OnSessionExpirationUpdate(session_id,
                                      new_expiry_time_sec.ToDoubleT());
 }
diff --git a/media/mojo/services/mojo_decryptor_service.cc b/media/mojo/services/mojo_decryptor_service.cc
index e96a74b..d675bb9 100644
--- a/media/mojo/services/mojo_decryptor_service.cc
+++ b/media/mojo/services/mojo_decryptor_service.cc
@@ -225,7 +225,8 @@
     DecryptAndDecodeVideoCallback callback,
     Status status,
     const scoped_refptr<VideoFrame>& frame) {
-  DVLOG_IF(1, status != Status::kSuccess) << __func__ << "(" << status << ")";
+  DVLOG_IF(1, status != Status::kSuccess)
+      << __func__ << ": status = " << status;
   DVLOG_IF(3, status == Status::kSuccess) << __func__;
 
   if (!frame) {
diff --git a/mojo/edk/embedder/platform_shared_buffer.cc b/mojo/edk/embedder/platform_shared_buffer.cc
index d94affb..6c689f385 100644
--- a/mojo/edk/embedder/platform_shared_buffer.cc
+++ b/mojo/edk/embedder/platform_shared_buffer.cc
@@ -14,6 +14,7 @@
 #include "base/memory/shared_memory.h"
 #include "base/process/process_handle.h"
 #include "base/sys_info.h"
+#include "build/build_config.h"
 #include "mojo/edk/embedder/platform_handle_utils.h"
 
 #if defined(OS_NACL)
@@ -247,6 +248,9 @@
 #elif defined(OS_MACOSX) && !defined(OS_IOS)
   base::SharedMemoryHandle handle = base::SharedMemoryHandle(
       platform_handle.release().port, num_bytes_, guid);
+#elif defined(OS_FUCHSIA)
+  base::SharedMemoryHandle handle =
+      base::SharedMemoryHandle(platform_handle.release(), num_bytes_, guid);
 #else
   base::SharedMemoryHandle handle(
       base::FileDescriptor(platform_handle.release().handle, false), num_bytes_,
diff --git a/mojo/edk/system/broker_host.cc b/mojo/edk/system/broker_host.cc
index 4796e33..4a3409a 100644
--- a/mojo/edk/system/broker_host.cc
+++ b/mojo/edk/system/broker_host.cc
@@ -20,9 +20,12 @@
 namespace edk {
 
 BrokerHost::BrokerHost(base::ProcessHandle client_process,
-                       ScopedPlatformHandle platform_handle)
+                       ScopedPlatformHandle platform_handle,
+                       const ProcessErrorCallback& process_error_callback)
+    : process_error_callback_(process_error_callback)
 #if defined(OS_WIN)
-    : client_process_(client_process)
+      ,
+      client_process_(client_process)
 #endif
 {
   CHECK(platform_handle.is_valid());
@@ -146,12 +149,17 @@
       break;
 
     default:
-      LOG(ERROR) << "Unexpected broker message type: " << header->type;
+      DLOG(ERROR) << "Unexpected broker message type: " << header->type;
       break;
   }
 }
 
-void BrokerHost::OnChannelError() {
+void BrokerHost::OnChannelError(Channel::Error error) {
+  if (process_error_callback_ &&
+      error == Channel::Error::kReceivedMalformedData) {
+    process_error_callback_.Run("Broker host received malformed message");
+  }
+
   delete this;
 }
 
diff --git a/mojo/edk/system/broker_host.h b/mojo/edk/system/broker_host.h
index a7995d2b..6555180e 100644
--- a/mojo/edk/system/broker_host.h
+++ b/mojo/edk/system/broker_host.h
@@ -11,6 +11,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/process/process_handle.h"
 #include "base/strings/string_piece.h"
+#include "mojo/edk/embedder/embedder.h"
 #include "mojo/edk/embedder/platform_handle_vector.h"
 #include "mojo/edk/embedder/scoped_platform_handle.h"
 #include "mojo/edk/system/channel.h"
@@ -23,7 +24,9 @@
 class BrokerHost : public Channel::Delegate,
                    public base::MessageLoop::DestructionObserver {
  public:
-  BrokerHost(base::ProcessHandle client_process, ScopedPlatformHandle handle);
+  BrokerHost(base::ProcessHandle client_process,
+             ScopedPlatformHandle handle,
+             const ProcessErrorCallback& process_error_callback);
 
   // Send |handle| to the child, to be used to establish a NodeChannel to us.
   bool SendChannel(ScopedPlatformHandle handle);
@@ -42,13 +45,15 @@
   void OnChannelMessage(const void* payload,
                         size_t payload_size,
                         ScopedPlatformHandleVectorPtr handles) override;
-  void OnChannelError() override;
+  void OnChannelError(Channel::Error error) override;
 
   // base::MessageLoop::DestructionObserver:
   void WillDestroyCurrentMessageLoop() override;
 
   void OnBufferRequest(uint32_t num_bytes);
 
+  const ProcessErrorCallback process_error_callback_;
+
 #if defined(OS_WIN)
   base::ProcessHandle client_process_;
 #endif
diff --git a/mojo/edk/system/channel.cc b/mojo/edk/system/channel.cc
index 7ded3dde..bfec79f 100644
--- a/mojo/edk/system/channel.cc
+++ b/mojo/edk/system/channel.cc
@@ -670,9 +670,9 @@
   return true;
 }
 
-void Channel::OnError() {
+void Channel::OnError(Error error) {
   if (delegate_)
-    delegate_->OnChannelError();
+    delegate_->OnChannelError(error);
 }
 
 bool Channel::OnControlMessage(Message::MessageType message_type,
diff --git a/mojo/edk/system/channel.h b/mojo/edk/system/channel.h
index 33a510c..cc3fa96 100644
--- a/mojo/edk/system/channel.h
+++ b/mojo/edk/system/channel.h
@@ -191,6 +191,21 @@
     DISALLOW_COPY_AND_ASSIGN(Message);
   };
 
+  // Error types which may be reported by a Channel instance to its delegate.
+  enum class Error {
+    // The remote end of the channel has been closed, either explicitly or
+    // because the process which hosted it is gone.
+    kDisconnected,
+
+    // For connection-oriented channels (e.g. named pipes), an unexpected error
+    // occurred during channel connection.
+    kConnectionFailed,
+
+    // Some incoming data failed validation, implying either a buggy or
+    // compromised sender.
+    kReceivedMalformedData,
+  };
+
   // Delegate methods are called from the I/O task runner with which the Channel
   // was created (see Channel::Create).
   class Delegate {
@@ -205,7 +220,7 @@
                                   ScopedPlatformHandleVectorPtr handles) = 0;
 
     // Notify that an error has occured and the Channel will cease operation.
-    virtual void OnChannelError() = 0;
+    virtual void OnChannelError(Error error) = 0;
   };
 
   // Creates a new Channel around a |platform_handle|, taking ownership of the
@@ -260,7 +275,7 @@
 
   // Called by the implementation when something goes horribly wrong. It is NOT
   // OK to call this synchronously from any public interface methods.
-  void OnError();
+  void OnError(Error error);
 
   // Retrieves the set of platform handles read for a given message.
   // |extra_header| and |extra_header_size| correspond to the extra header data.
diff --git a/mojo/edk/system/channel_posix.cc b/mojo/edk/system/channel_posix.cc
index d067e60..b545933d 100644
--- a/mojo/edk/system/channel_posix.cc
+++ b/mojo/edk/system/channel_posix.cc
@@ -133,8 +133,9 @@
     if (write_error) {
       // Do not synchronously invoke OnError(). Write() may have been called by
       // the delegate and we don't want to re-enter it.
-      io_task_runner_->PostTask(FROM_HERE,
-                                base::Bind(&ChannelPosix::OnError, this));
+      io_task_runner_->PostTask(
+          FROM_HERE,
+          base::Bind(&ChannelPosix::OnError, this, Error::kDisconnected));
     }
   }
 
@@ -288,7 +289,7 @@
       ScopedPlatformHandle accept_fd;
       ServerAcceptConnection(handle_.get(), &accept_fd);
       if (!accept_fd.is_valid()) {
-        OnError();
+        OnError(Error::kConnectionFailed);
         return;
       }
       handle_ = std::move(accept_fd);
@@ -299,6 +300,7 @@
       return;
     }
 
+    bool validation_error = false;
     bool read_error = false;
     size_t next_read_size = 0;
     size_t buffer_capacity = 0;
@@ -317,6 +319,7 @@
         total_bytes_read += bytes_read;
         if (!OnReadComplete(bytes_read, &next_read_size)) {
           read_error = true;
+          validation_error = true;
           break;
         }
       } else if (read_result == 0 ||
@@ -329,8 +332,10 @@
     if (read_error) {
       // Stop receiving read notifications.
       read_watcher_.reset();
-
-      OnError();
+      if (validation_error)
+        OnError(Error::kReceivedMalformedData);
+      else
+        OnError(Error::kDisconnected);
     }
   }
 
@@ -343,7 +348,7 @@
         reject_writes_ = write_error = true;
     }
     if (write_error)
-      OnError();
+      OnError(Error::kDisconnected);
   }
 
   // Attempts to write a message directly to the channel. If the full message
diff --git a/mojo/edk/system/channel_unittest.cc b/mojo/edk/system/channel_unittest.cc
index ce2c804..8db7256 100644
--- a/mojo/edk/system/channel_unittest.cc
+++ b/mojo/edk/system/channel_unittest.cc
@@ -57,7 +57,7 @@
   }
 
   // Notify that an error has occured and the Channel will cease operation.
-  void OnChannelError() override {}
+  void OnChannelError(Channel::Error error) override {}
 
  private:
   size_t payload_size_ = 0;
diff --git a/mojo/edk/system/channel_win.cc b/mojo/edk/system/channel_win.cc
index 2ca035a..d52decd 100644
--- a/mojo/edk/system/channel_win.cc
+++ b/mojo/edk/system/channel_win.cc
@@ -112,8 +112,9 @@
     if (write_error) {
       // Do not synchronously invoke OnError(). Write() may have been called by
       // the delegate and we don't want to re-enter it.
-      io_task_runner_->PostTask(FROM_HERE,
-                                base::Bind(&ChannelWin::OnError, this));
+      io_task_runner_->PostTask(
+          FROM_HERE,
+          base::Bind(&ChannelWin::OnError, this, Error::kDisconnected));
     }
   }
 
@@ -158,7 +159,7 @@
                                  &connect_context_.overlapped);
       if (ok) {
         PLOG(ERROR) << "Unexpected success while waiting for pipe connection";
-        OnError();
+        OnError(Error::kConnectionFailed);
         return;
       }
 
@@ -171,7 +172,7 @@
           AddRef();
           return;
         case ERROR_NO_DATA:
-          OnError();
+          OnError(Error::kConnectionFailed);
           return;
       }
     }
@@ -217,7 +218,7 @@
                      DWORD bytes_transfered,
                      DWORD error) override {
     if (error != ERROR_SUCCESS) {
-      OnError();
+      OnError(Error::kDisconnected);
     } else if (context == &connect_context_) {
       DCHECK(wait_for_connect_);
       wait_for_connect_ = false;
@@ -243,10 +244,10 @@
       if (OnReadComplete(bytes_read, &next_read_size)) {
         ReadMore(next_read_size);
       } else {
-        OnError();
+        OnError(Error::kReceivedMalformedData);
       }
     } else if (bytes_read == 0) {
-      OnError();
+      OnError(Error::kDisconnected);
     }
   }
 
@@ -276,7 +277,7 @@
         reject_writes_ = write_error = true;
     }
     if (write_error)
-      OnError();
+      OnError(Error::kDisconnected);
   }
 
   void ReadMore(size_t next_read_size_hint) {
@@ -293,7 +294,7 @@
     if (ok || GetLastError() == ERROR_IO_PENDING) {
       AddRef();  // Will be balanced in OnIOCompleted
     } else {
-      OnError();
+      OnError(Error::kDisconnected);
     }
   }
 
diff --git a/mojo/edk/system/node_channel.cc b/mojo/edk/system/node_channel.cc
index 813a01d..7e7bdc2 100644
--- a/mojo/edk/system/node_channel.cc
+++ b/mojo/edk/system/node_channel.cc
@@ -755,19 +755,28 @@
     }
 
     default:
-      break;
+      // Ignore unrecognized message types, allowing for future extensibility.
+      return;
   }
 
   DLOG(ERROR) << "Received invalid message. Closing channel.";
+  if (process_error_callback_)
+    process_error_callback_.Run("NodeChannel received a malformed message");
   delegate_->OnChannelError(remote_node_name_, this);
 }
 
-void NodeChannel::OnChannelError() {
+void NodeChannel::OnChannelError(Channel::Error error) {
   DCHECK(io_task_runner_->RunsTasksInCurrentSequence());
 
   RequestContext request_context(RequestContext::Source::SYSTEM);
 
   ShutDown();
+
+  if (process_error_callback_ &&
+      error == Channel::Error::kReceivedMalformedData) {
+    process_error_callback_.Run("Channel received a malformed message");
+  }
+
   // |OnChannelError()| may cause |this| to be destroyed, but still need access
   // to the name name after that destruction. So may a copy of
   // |remote_node_name_| so it can be used if |this| becomes destroyed.
diff --git a/mojo/edk/system/node_channel.h b/mojo/edk/system/node_channel.h
index 9ca2eb9..c962c6b 100644
--- a/mojo/edk/system/node_channel.h
+++ b/mojo/edk/system/node_channel.h
@@ -178,7 +178,7 @@
   void OnChannelMessage(const void* payload,
                         size_t payload_size,
                         ScopedPlatformHandleVectorPtr handles) override;
-  void OnChannelError() override;
+  void OnChannelError(Channel::Error error) override;
 
 #if defined(OS_MACOSX) && !defined(OS_IOS)
   // MachPortRelay::Observer:
diff --git a/mojo/edk/system/node_controller.cc b/mojo/edk/system/node_controller.cc
index 7202849..865ebb6 100644
--- a/mojo/edk/system/node_controller.cc
+++ b/mojo/edk/system/node_controller.cc
@@ -366,7 +366,8 @@
   ScopedPlatformHandle server_handle = node_channel.PassServerHandle();
   // BrokerHost owns itself.
   BrokerHost* broker_host =
-      new BrokerHost(target_process, connection_params.TakeChannelHandle());
+      new BrokerHost(target_process, connection_params.TakeChannelHandle(),
+                     process_error_callback);
   bool channel_ok = broker_host->SendChannel(node_channel.PassClientHandle());
 
 #if defined(OS_WIN)
diff --git a/mojo/edk/system/platform_wrapper_unittest.cc b/mojo/edk/system/platform_wrapper_unittest.cc
index aa153dd..a88563f 100644
--- a/mojo/edk/system/platform_wrapper_unittest.cc
+++ b/mojo/edk/system/platform_wrapper_unittest.cc
@@ -13,6 +13,7 @@
 #include "base/files/file_util.h"
 #include "base/memory/shared_memory.h"
 #include "base/process/process_handle.h"
+#include "build/build_config.h"
 #include "mojo/edk/embedder/platform_shared_buffer.h"
 #include "mojo/edk/test/mojo_test_base.h"
 #include "mojo/public/c/system/platform_handle.h"
@@ -125,10 +126,10 @@
     os_buffer.type = SHARED_BUFFER_PLATFORM_HANDLE_TYPE;
 #if defined(OS_MACOSX) && !defined(OS_IOS)
     os_buffer.value = static_cast<uint64_t>(memory_handle.GetMemoryObject());
-#elif defined(OS_POSIX)
-  os_buffer.value = static_cast<uint64_t>(memory_handle.GetHandle());
 #elif defined(OS_WIN)
-  os_buffer.value = reinterpret_cast<uint64_t>(memory_handle.GetHandle());
+    os_buffer.value = reinterpret_cast<uint64_t>(memory_handle.GetHandle());
+#else
+    os_buffer.value = static_cast<uint64_t>(memory_handle.GetHandle());
 #endif
 
     MojoSharedBufferGuid mojo_guid;
@@ -180,6 +181,10 @@
   ASSERT_EQ(MOJO_PLATFORM_HANDLE_TYPE_MACH_PORT, os_buffer.type);
   base::SharedMemoryHandle memory_handle(
       static_cast<mach_port_t>(os_buffer.value), size, guid);
+#elif defined(OS_FUCHSIA)
+  ASSERT_EQ(MOJO_PLATFORM_HANDLE_TYPE_FUCHSIA_HANDLE, os_buffer.type);
+  base::SharedMemoryHandle memory_handle(
+      static_cast<mx_handle_t>(os_buffer.value), size, guid);
 #elif defined(OS_POSIX)
   ASSERT_EQ(MOJO_PLATFORM_HANDLE_TYPE_FILE_DESCRIPTOR, os_buffer.type);
   base::SharedMemoryHandle memory_handle(
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
index e105918c..3eb2006 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/interface_definition.tmpl
@@ -255,8 +255,8 @@
 
 bool {{class_name}}_{{method.name}}_ForwardToCallback::Accept(
     mojo::Message* message) {
-{%-     if method|method_supports_lazy_serialization %}
   mojo::internal::MessageDispatchContext dispatch_context(message);
+{%-     if method|method_supports_lazy_serialization %}
   if (!message->is_serialized()) {
     auto context =
         message->TakeUnserializedContext<{{response_message_typename}}>();
diff --git a/net/cert/internal/parse_ocsp.cc b/net/cert/internal/parse_ocsp.cc
index aa11ada..f144ad70 100644
--- a/net/cert/internal/parse_ocsp.cc
+++ b/net/cert/internal/parse_ocsp.cc
@@ -324,7 +324,7 @@
   if (!parser.ReadRawTLV(&sigalg_tlv))
     return false;
   // TODO(crbug.com/634443): Propagate the errors.
-  net::CertErrors errors;
+  CertErrors errors;
   out->signature_algorithm = SignatureAlgorithm::Create(sigalg_tlv, &errors);
   if (!out->signature_algorithm)
     return false;
diff --git a/net/cert/internal/test_helpers.cc b/net/cert/internal/test_helpers.cc
index 979cccaf..0857250 100644
--- a/net/cert/internal/test_helpers.cc
+++ b/net/cert/internal/test_helpers.cc
@@ -161,7 +161,7 @@
     const std::string& block_data = pem_tokenizer.data();
 
     CertErrors errors;
-    if (!net::ParsedCertificate::CreateAndAddToVector(
+    if (!ParsedCertificate::CreateAndAddToVector(
             bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
                 reinterpret_cast<const uint8_t*>(block_data.data()),
                 block_data.size(), nullptr)),
diff --git a/net/cert/internal/verify_certificate_chain_pkits_unittest.cc b/net/cert/internal/verify_certificate_chain_pkits_unittest.cc
index 1c342da..e9b64f24 100644
--- a/net/cert/internal/verify_certificate_chain_pkits_unittest.cc
+++ b/net/cert/internal/verify_certificate_chain_pkits_unittest.cc
@@ -32,10 +32,10 @@
     // PKITS lists chains from trust anchor to target, whereas
     // VerifyCertificateChain takes them starting with the target and ending
     // with the trust anchor.
-    std::vector<scoped_refptr<net::ParsedCertificate>> input_chain;
+    std::vector<scoped_refptr<ParsedCertificate>> input_chain;
     CertErrors parsing_errors;
     for (auto i = cert_ders.rbegin(); i != cert_ders.rend(); ++i) {
-      ASSERT_TRUE(net::ParsedCertificate::CreateAndAddToVector(
+      ASSERT_TRUE(ParsedCertificate::CreateAndAddToVector(
           bssl::UniquePtr<CRYPTO_BUFFER>(CRYPTO_BUFFER_new(
               reinterpret_cast<const uint8_t*>(i->data()), i->size(), nullptr)),
           {}, &input_chain, &parsing_errors))
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc
index 8145802..47837fa 100644
--- a/net/cookies/cookie_monster.cc
+++ b/net/cookies/cookie_monster.cc
@@ -82,9 +82,9 @@
 //
 // On the browser critical paths (e.g. for loading initial web pages in a
 // session restore) it may take too long to wait for the full load. If a cookie
-// request is for a specific URL, DoCookieTaskForURL is called, which triggers a
-// priority load if the key is not loaded yet by calling PersistentCookieStore
-// :: LoadCookiesForKey. The request is queued in
+// request is for a specific URL, DoCookieCallbackForURL is called, which
+// triggers a priority load if the key is not loaded yet by calling
+// PersistentCookieStore::LoadCookiesForKey. The request is queued in
 // CookieMonster::tasks_pending_for_key_ and executed upon receiving
 // notification of key load completion via CookieMonster::OnKeyLoaded(). If
 // multiple requests for the same eTLD+1 are received before key load
@@ -102,6 +102,31 @@
 const char kAlwaysFetchName[] = "AlwaysFetch";
 const char kCookieMonsterFetchStrategyName[] = "CookieMonsterFetchStrategy";
 
+void MayeRunDeleteCallback(base::WeakPtr<net::CookieMonster> cookie_monster,
+                           base::OnceClosure callback) {
+  if (cookie_monster && callback)
+    std::move(callback).Run();
+}
+
+void MaybeRunCookieCallback(base::OnceClosure callback) {
+  if (callback)
+    std::move(callback).Run();
+}
+
+template <typename T>
+void MaybeRunCookieCallback(base::OnceCallback<void(const T&)> callback,
+                            const T& result) {
+  if (callback)
+    std::move(callback).Run(result);
+}
+
+template <typename T>
+void MaybeRunCookieCallback(base::OnceCallback<void(T)> callback,
+                            const T& result) {
+  if (callback)
+    std::move(callback).Run(result);
+}
+
 }  // namespace
 
 namespace net {
@@ -385,516 +410,6 @@
       kDefaultCookieableSchemes + kDefaultCookieableSchemesCount);
 }
 
-// Task classes for queueing the coming request.
-
-class CookieMonster::CookieMonsterTask
-    : public base::RefCountedThreadSafe<CookieMonsterTask> {
- public:
-  // Runs the task and invokes the client callback on the thread that
-  // originally constructed the task.
-  virtual void Run() = 0;
-
- protected:
-  explicit CookieMonsterTask(CookieMonster* cookie_monster);
-  virtual ~CookieMonsterTask();
-
-  CookieMonster* cookie_monster() { return cookie_monster_; }
-
- private:
-  friend class base::RefCountedThreadSafe<CookieMonsterTask>;
-
-  CookieMonster* cookie_monster_;
-
-  DISALLOW_COPY_AND_ASSIGN(CookieMonsterTask);
-};
-
-CookieMonster::CookieMonsterTask::CookieMonsterTask(
-    CookieMonster* cookie_monster)
-    : cookie_monster_(cookie_monster) {}
-
-CookieMonster::CookieMonsterTask::~CookieMonsterTask() {
-}
-
-// Task class for SetCookieWithDetails call.
-class CookieMonster::SetCookieWithDetailsTask : public CookieMonsterTask {
- public:
-  SetCookieWithDetailsTask(CookieMonster* cookie_monster,
-                           const GURL& url,
-                           const std::string& name,
-                           const std::string& value,
-                           const std::string& domain,
-                           const std::string& path,
-                           base::Time creation_time,
-                           base::Time expiration_time,
-                           base::Time last_access_time,
-                           bool secure,
-                           bool http_only,
-                           CookieSameSite same_site,
-                           CookiePriority priority,
-                           SetCookiesCallback callback)
-      : CookieMonsterTask(cookie_monster),
-        url_(url),
-        name_(name),
-        value_(value),
-        domain_(domain),
-        path_(path),
-        creation_time_(creation_time),
-        expiration_time_(expiration_time),
-        last_access_time_(last_access_time),
-        secure_(secure),
-        http_only_(http_only),
-        same_site_(same_site),
-        priority_(priority),
-        callback_(std::move(callback)) {}
-
-  // CookieMonsterTask:
-  void Run() override;
-
- protected:
-  ~SetCookieWithDetailsTask() override {}
-
- private:
-  GURL url_;
-  std::string name_;
-  std::string value_;
-  std::string domain_;
-  std::string path_;
-  base::Time creation_time_;
-  base::Time expiration_time_;
-  base::Time last_access_time_;
-  bool secure_;
-  bool http_only_;
-  CookieSameSite same_site_;
-  CookiePriority priority_;
-  SetCookiesCallback callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(SetCookieWithDetailsTask);
-};
-
-void CookieMonster::SetCookieWithDetailsTask::Run() {
-  bool success = this->cookie_monster()->SetCookieWithDetails(
-      url_, name_, value_, domain_, path_, creation_time_, expiration_time_,
-      last_access_time_, secure_, http_only_, same_site_, priority_);
-  if (!callback_.is_null())
-    std::move(callback_).Run(success);
-}
-
-// Task class for GetAllCookies call.
-class CookieMonster::GetAllCookiesTask : public CookieMonsterTask {
- public:
-  GetAllCookiesTask(CookieMonster* cookie_monster,
-                    GetCookieListCallback callback)
-      : CookieMonsterTask(cookie_monster), callback_(std::move(callback)) {}
-
-  // CookieMonsterTask
-  void Run() override;
-
- protected:
-  ~GetAllCookiesTask() override {}
-
- private:
-  GetCookieListCallback callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(GetAllCookiesTask);
-};
-
-void CookieMonster::GetAllCookiesTask::Run() {
-  if (!callback_.is_null()) {
-    CookieList cookies = this->cookie_monster()->GetAllCookies();
-    std::move(callback_).Run(cookies);
-  }
-}
-
-// Task class for GetCookieListWithOptionsAsync call.
-class CookieMonster::GetCookieListWithOptionsTask : public CookieMonsterTask {
- public:
-  GetCookieListWithOptionsTask(CookieMonster* cookie_monster,
-                               const GURL& url,
-                               const CookieOptions& options,
-                               GetCookieListCallback callback)
-      : CookieMonsterTask(cookie_monster),
-        url_(url),
-        options_(options),
-        callback_(std::move(callback)) {}
-
-  // CookieMonsterTask:
-  void Run() override;
-
- protected:
-  ~GetCookieListWithOptionsTask() override {}
-
- private:
-  GURL url_;
-  CookieOptions options_;
-  GetCookieListCallback callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(GetCookieListWithOptionsTask);
-};
-
-void CookieMonster::GetCookieListWithOptionsTask::Run() {
-  if (!callback_.is_null()) {
-    CookieList cookies =
-        this->cookie_monster()->GetCookieListWithOptions(url_, options_);
-    std::move(callback_).Run(cookies);
-  }
-}
-
-template <typename Result>
-struct CallbackType {
-  typedef base::OnceCallback<void(Result)> Type;
-};
-
-template <>
-struct CallbackType<void> {
-  typedef base::OnceClosure Type;
-};
-
-// Base task class for Delete*Task.
-template <typename Result>
-class CookieMonster::DeleteTask : public CookieMonsterTask {
- public:
-  DeleteTask(CookieMonster* cookie_monster,
-             typename CallbackType<Result>::Type callback)
-      : CookieMonsterTask(cookie_monster), callback_(std::move(callback)) {}
-
-  // CookieMonsterTask:
-  void Run() override;
-
- protected:
-  ~DeleteTask() override;
-
- private:
-  // Runs the delete task and returns a result.
-  virtual Result RunDeleteTask() = 0;
-  // Runs the delete task and then returns a callback to be called after
-  // flushing the persistent store.
-  // TODO(mmenke): This seems like a pretty ugly and needlessly confusing API.
-  // Simplify it?
-  base::OnceClosure RunDeleteTaskAndBindCallback();
-
-  typename CallbackType<Result>::Type callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeleteTask);
-};
-
-template <typename Result>
-CookieMonster::DeleteTask<Result>::~DeleteTask() {
-}
-
-template <typename Result>
-base::OnceClosure
-CookieMonster::DeleteTask<Result>::RunDeleteTaskAndBindCallback() {
-  Result result = RunDeleteTask();
-  if (callback_.is_null())
-    return base::OnceClosure();
-  return base::BindOnce(std::move(callback_), result);
-}
-
-template <>
-base::OnceClosure
-CookieMonster::DeleteTask<void>::RunDeleteTaskAndBindCallback() {
-  RunDeleteTask();
-  return std::move(callback_);
-}
-
-template <typename Result>
-void CookieMonster::DeleteTask<Result>::Run() {
-  base::OnceClosure callback = RunDeleteTaskAndBindCallback();
-  if (!callback.is_null()) {
-    callback =
-        base::BindOnce(&CookieMonster::RunCallback,
-                       this->cookie_monster()->weak_ptr_factory_.GetWeakPtr(),
-                       std::move(callback));
-  }
-  this->cookie_monster()->FlushStore(std::move(callback));
-}
-
-// Task class for DeleteAllCreatedBetween call.
-class CookieMonster::DeleteAllCreatedBetweenTask : public DeleteTask<uint32_t> {
- public:
-  DeleteAllCreatedBetweenTask(CookieMonster* cookie_monster,
-                              const Time& delete_begin,
-                              const Time& delete_end,
-                              DeleteCallback callback)
-      : DeleteTask<uint32_t>(cookie_monster, std::move(callback)),
-        delete_begin_(delete_begin),
-        delete_end_(delete_end) {}
-
-  // DeleteTask:
-  uint32_t RunDeleteTask() override;
-
- protected:
-  ~DeleteAllCreatedBetweenTask() override {}
-
- private:
-  Time delete_begin_;
-  Time delete_end_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeleteAllCreatedBetweenTask);
-};
-
-uint32_t CookieMonster::DeleteAllCreatedBetweenTask::RunDeleteTask() {
-  return this->cookie_monster()->DeleteAllCreatedBetween(delete_begin_,
-                                                         delete_end_);
-}
-
-// Task class for DeleteAllCreatedBetweenWithPredicate call.
-class CookieMonster::DeleteAllCreatedBetweenWithPredicateTask
-    : public DeleteTask<uint32_t> {
- public:
-  DeleteAllCreatedBetweenWithPredicateTask(
-      CookieMonster* cookie_monster,
-      Time delete_begin,
-      Time delete_end,
-      base::Callback<bool(const CanonicalCookie&)> predicate,
-      DeleteCallback callback)
-      : DeleteTask<uint32_t>(cookie_monster, std::move(callback)),
-        delete_begin_(delete_begin),
-        delete_end_(delete_end),
-        predicate_(predicate) {}
-
-  // DeleteTask:
-  uint32_t RunDeleteTask() override;
-
- protected:
-  ~DeleteAllCreatedBetweenWithPredicateTask() override {}
-
- private:
-  Time delete_begin_;
-  Time delete_end_;
-  base::Callback<bool(const CanonicalCookie&)> predicate_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeleteAllCreatedBetweenWithPredicateTask);
-};
-
-uint32_t
-CookieMonster::DeleteAllCreatedBetweenWithPredicateTask::RunDeleteTask() {
-  return this->cookie_monster()->DeleteAllCreatedBetweenWithPredicate(
-      delete_begin_, delete_end_, predicate_);
-}
-
-// Task class for DeleteCanonicalCookie call.
-class CookieMonster::DeleteCanonicalCookieTask : public DeleteTask<uint32_t> {
- public:
-  DeleteCanonicalCookieTask(CookieMonster* cookie_monster,
-                            const CanonicalCookie& cookie,
-                            DeleteCallback callback)
-      : DeleteTask<uint32_t>(cookie_monster, std::move(callback)),
-        cookie_(cookie) {}
-
-  // DeleteTask:
-  uint32_t RunDeleteTask() override;
-
- protected:
-  ~DeleteCanonicalCookieTask() override {}
-
- private:
-  CanonicalCookie cookie_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeleteCanonicalCookieTask);
-};
-
-uint32_t CookieMonster::DeleteCanonicalCookieTask::RunDeleteTask() {
-  return this->cookie_monster()->DeleteCanonicalCookie(cookie_);
-}
-
-// Task class for SetCanonicalCookie call.
-class CookieMonster::SetCanonicalCookieTask : public CookieMonsterTask {
- public:
-  SetCanonicalCookieTask(CookieMonster* cookie_monster,
-                         std::unique_ptr<CanonicalCookie> cookie,
-                         bool secure_source,
-                         bool modify_http_only,
-                         SetCookiesCallback callback)
-      : CookieMonsterTask(cookie_monster),
-        cookie_(std::move(cookie)),
-        secure_source_(secure_source),
-        modify_http_only_(modify_http_only),
-        callback_(std::move(callback)) {}
-
-  // CookieMonsterTask:
-  void Run() override;
-
- protected:
-  ~SetCanonicalCookieTask() override {}
-
- private:
-  std::unique_ptr<CanonicalCookie> cookie_;
-  bool secure_source_;
-  bool modify_http_only_;
-  SetCookiesCallback callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(SetCanonicalCookieTask);
-};
-
-void CookieMonster::SetCanonicalCookieTask::Run() {
-  bool result = this->cookie_monster()->SetCanonicalCookie(
-      std::move(cookie_), secure_source_, modify_http_only_);
-  if (!callback_.is_null())
-    std::move(callback_).Run(result);
-}
-
-// Task class for SetCookieWithOptions call.
-class CookieMonster::SetCookieWithOptionsTask : public CookieMonsterTask {
- public:
-  SetCookieWithOptionsTask(CookieMonster* cookie_monster,
-                           const GURL& url,
-                           const std::string& cookie_line,
-                           const CookieOptions& options,
-                           SetCookiesCallback callback)
-      : CookieMonsterTask(cookie_monster),
-        url_(url),
-        cookie_line_(cookie_line),
-        options_(options),
-        callback_(std::move(callback)) {}
-
-  // CookieMonsterTask:
-  void Run() override;
-
- protected:
-  ~SetCookieWithOptionsTask() override {}
-
- private:
-  GURL url_;
-  std::string cookie_line_;
-  CookieOptions options_;
-  SetCookiesCallback callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(SetCookieWithOptionsTask);
-};
-
-void CookieMonster::SetCookieWithOptionsTask::Run() {
-  bool result = this->cookie_monster()->SetCookieWithOptions(url_, cookie_line_,
-                                                             options_);
-  if (!callback_.is_null())
-    std::move(callback_).Run(result);
-}
-
-// Task class for SetAllCookies call.
-class CookieMonster::SetAllCookiesTask : public CookieMonsterTask {
- public:
-  SetAllCookiesTask(CookieMonster* cookie_monster,
-                    const CookieList& list,
-                    SetCookiesCallback callback)
-      : CookieMonsterTask(cookie_monster),
-        list_(list),
-        callback_(std::move(callback)) {}
-
-  // CookieMonsterTask:
-  void Run() override;
-
- protected:
-  ~SetAllCookiesTask() override {}
-
- private:
-  CookieList list_;
-  SetCookiesCallback callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(SetAllCookiesTask);
-};
-
-void CookieMonster::SetAllCookiesTask::Run() {
-  CookieList positive_diff;
-  CookieList negative_diff;
-  CookieList old_cookies = this->cookie_monster()->GetAllCookies();
-  this->cookie_monster()->ComputeCookieDiff(&old_cookies, &list_,
-                                            &positive_diff, &negative_diff);
-
-  for (CookieList::const_iterator it = negative_diff.begin();
-       it != negative_diff.end(); ++it) {
-    this->cookie_monster()->DeleteCanonicalCookie(*it);
-  }
-
-  bool result = true;
-  if (positive_diff.size() > 0)
-    result = this->cookie_monster()->SetAllCookies(list_);
-
-  if (!callback_.is_null())
-    std::move(callback_).Run(result);
-}
-
-// Task class for GetCookiesWithOptions call.
-class CookieMonster::GetCookiesWithOptionsTask : public CookieMonsterTask {
- public:
-  GetCookiesWithOptionsTask(CookieMonster* cookie_monster,
-                            const GURL& url,
-                            const CookieOptions& options,
-                            GetCookiesCallback callback)
-      : CookieMonsterTask(cookie_monster),
-        url_(url),
-        options_(options),
-        callback_(std::move(callback)) {}
-
-  // CookieMonsterTask:
-  void Run() override;
-
- protected:
-  ~GetCookiesWithOptionsTask() override {}
-
- private:
-  GURL url_;
-  CookieOptions options_;
-  GetCookiesCallback callback_;
-
-  DISALLOW_COPY_AND_ASSIGN(GetCookiesWithOptionsTask);
-};
-
-void CookieMonster::GetCookiesWithOptionsTask::Run() {
-  std::string cookie =
-      this->cookie_monster()->GetCookiesWithOptions(url_, options_);
-  if (!callback_.is_null())
-    std::move(callback_).Run(cookie);
-}
-
-// Task class for DeleteCookie call.
-class CookieMonster::DeleteCookieTask : public DeleteTask<void> {
- public:
-  DeleteCookieTask(CookieMonster* cookie_monster,
-                   const GURL& url,
-                   const std::string& cookie_name,
-                   base::OnceClosure callback)
-      : DeleteTask<void>(cookie_monster, std::move(callback)),
-        url_(url),
-        cookie_name_(cookie_name) {}
-
-  // DeleteTask:
-  void RunDeleteTask() override;
-
- protected:
-  ~DeleteCookieTask() override {}
-
- private:
-  GURL url_;
-  std::string cookie_name_;
-
-  DISALLOW_COPY_AND_ASSIGN(DeleteCookieTask);
-};
-
-void CookieMonster::DeleteCookieTask::RunDeleteTask() {
-  this->cookie_monster()->DeleteCookie(url_, cookie_name_);
-}
-
-// Task class for DeleteSessionCookies call.
-class CookieMonster::DeleteSessionCookiesTask : public DeleteTask<uint32_t> {
- public:
-  DeleteSessionCookiesTask(CookieMonster* cookie_monster,
-                           DeleteCallback callback)
-      : DeleteTask<uint32_t>(cookie_monster, std::move(callback)) {}
-
-  // DeleteTask:
-  uint32_t RunDeleteTask() override;
-
- protected:
-  ~DeleteSessionCookiesTask() override {}
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(DeleteSessionCookiesTask);
-};
-
-uint32_t CookieMonster::DeleteSessionCookiesTask::RunDeleteTask() {
-  return this->cookie_monster()->DeleteSessionCookies();
-}
-
 // Asynchronous CookieMonster API
 
 void CookieMonster::SetCookieWithDetailsAsync(const GURL& url,
@@ -910,11 +425,16 @@
                                               CookieSameSite same_site,
                                               CookiePriority priority,
                                               SetCookiesCallback callback) {
-  scoped_refptr<SetCookieWithDetailsTask> task = new SetCookieWithDetailsTask(
-      this, url, name, value, domain, path, creation_time, expiration_time,
-      last_access_time, secure, http_only, same_site, priority,
-      std::move(callback));
-  DoCookieTaskForURL(task, url);
+  DoCookieCallbackForURL(
+      base::BindOnce(
+          // base::Unretained is safe as DoCookieCallbackForURL stores
+          // the callback on |*this|, so the callback will not outlive
+          // the object.
+          &CookieMonster::SetCookieWithDetails, base::Unretained(this), url,
+          name, value, domain, path, creation_time, expiration_time,
+          last_access_time, secure, http_only, same_site, priority,
+          std::move(callback)),
+      url);
 }
 
 void CookieMonster::FlushStore(base::OnceClosure callback) {
@@ -925,7 +445,7 @@
       channel_id_service_->GetChannelIDStore()->Flush();
     }
     store_->Flush(std::move(callback));
-  } else if (!callback.is_null()) {
+  } else if (callback) {
     base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
                                                   std::move(callback));
   }
@@ -940,9 +460,12 @@
 
 void CookieMonster::SetAllCookiesAsync(const CookieList& list,
                                        SetCookiesCallback callback) {
-  scoped_refptr<SetAllCookiesTask> task =
-      new SetAllCookiesTask(this, list, std::move(callback));
-  DoCookieTask(task);
+  DoCookieCallback(base::BindOnce(
+      // base::Unretained is safe as DoCookieCallbackForURL stores
+      // the callback on |*this|, so the callback will not outlive
+      // the object.
+      &CookieMonster::SetAllCookies, base::Unretained(this), list,
+      std::move(callback)));
 }
 
 void CookieMonster::SetCanonicalCookieAsync(
@@ -951,78 +474,102 @@
     bool modify_http_only,
     SetCookiesCallback callback) {
   DCHECK(cookie->IsCanonical());
-  scoped_refptr<SetCanonicalCookieTask> task =
-      new SetCanonicalCookieTask(this, std::move(cookie), secure_source,
-                                 modify_http_only, std::move(callback));
 
-  // TODO(rdsmith): Switch to DoCookieTaskForURL (or the equivalent).
+  // TODO(rdsmith): Switch to DoCookieCallbackForURL (or the equivalent).
   // This is tricky because we don't have the scheme in this routine
-  // and DoCookieTaskForURL uses cookie_util::GetEffectiveDomain(scheme, host)
+  // and DoCookieCallbackForURL uses
+  // cookie_util::GetEffectiveDomain(scheme, host)
   // to generate the database key to block behind.
-  DoCookieTask(task);
+  DoCookieCallback(base::BindOnce(
+      // base::Unretained is safe as DoCookieCallbackForURL stores
+      // the callback on |*this|, so the callback will not outlive
+      // the object.
+      &CookieMonster::SetCanonicalCookie, base::Unretained(this),
+      std::move(cookie), secure_source, modify_http_only, std::move(callback)));
 }
 
 void CookieMonster::SetCookieWithOptionsAsync(const GURL& url,
                                               const std::string& cookie_line,
                                               const CookieOptions& options,
                                               SetCookiesCallback callback) {
-  scoped_refptr<SetCookieWithOptionsTask> task = new SetCookieWithOptionsTask(
-      this, url, cookie_line, options, std::move(callback));
-
-  DoCookieTaskForURL(task, url);
+  DoCookieCallbackForURL(
+      base::BindOnce(
+          // base::Unretained is safe as DoCookieCallbackForURL stores
+          // the callback on |*this|, so the callback will not outlive
+          // the object.
+          &CookieMonster::SetCookieWithOptions, base::Unretained(this), url,
+          cookie_line, options, std::move(callback)),
+      url);
 }
 
 void CookieMonster::GetCookiesWithOptionsAsync(const GURL& url,
                                                const CookieOptions& options,
                                                GetCookiesCallback callback) {
-  scoped_refptr<GetCookiesWithOptionsTask> task =
-      new GetCookiesWithOptionsTask(this, url, options, std::move(callback));
-
-  DoCookieTaskForURL(task, url);
+  DoCookieCallbackForURL(
+      base::BindOnce(
+          // base::Unretained is safe as DoCookieCallbackForURL stores
+          // the callback on |*this|, so the callback will not outlive
+          // the object.
+          &CookieMonster::GetCookiesWithOptions, base::Unretained(this), url,
+          options, std::move(callback)),
+      url);
 }
 
 void CookieMonster::GetCookieListWithOptionsAsync(
     const GURL& url,
     const CookieOptions& options,
     GetCookieListCallback callback) {
-  scoped_refptr<GetCookieListWithOptionsTask> task =
-      new GetCookieListWithOptionsTask(this, url, options, std::move(callback));
-
-  DoCookieTaskForURL(task, url);
+  DoCookieCallbackForURL(
+      base::BindOnce(
+          // base::Unretained is safe as DoCookieCallbackForURL stores
+          // the callback on |*this|, so the callback will not outlive
+          // the object.
+          &CookieMonster::GetCookieListWithOptions, base::Unretained(this), url,
+          options, std::move(callback)),
+      url);
 }
 
 void CookieMonster::GetAllCookiesAsync(GetCookieListCallback callback) {
-  scoped_refptr<GetAllCookiesTask> task =
-      new GetAllCookiesTask(this, std::move(callback));
-
-  DoCookieTask(task);
+  DoCookieCallback(base::BindOnce(
+      // base::Unretained is safe as DoCookieCallbackForURL stores
+      // the callback on |*this|, so the callback will not outlive
+      // the object.
+      &CookieMonster::GetAllCookies, base::Unretained(this),
+      std::move(callback)));
 }
 
 void CookieMonster::DeleteCookieAsync(const GURL& url,
                                       const std::string& cookie_name,
                                       base::OnceClosure callback) {
-  scoped_refptr<DeleteCookieTask> task =
-      new DeleteCookieTask(this, url, cookie_name, std::move(callback));
-
-  DoCookieTaskForURL(task, url);
+  DoCookieCallbackForURL(
+      base::BindOnce(
+          // base::Unretained is safe as DoCookieCallbackForURL stores
+          // the callback on |*this|, so the callback will not outlive
+          // the object.
+          &CookieMonster::DeleteCookie, base::Unretained(this), url,
+          cookie_name, std::move(callback)),
+      url);
 }
 
 void CookieMonster::DeleteCanonicalCookieAsync(const CanonicalCookie& cookie,
                                                DeleteCallback callback) {
-  scoped_refptr<DeleteCanonicalCookieTask> task =
-      new DeleteCanonicalCookieTask(this, cookie, std::move(callback));
-
-  DoCookieTask(task);
+  DoCookieCallback(base::BindOnce(
+      // base::Unretained is safe as DoCookieCallbackForURL stores
+      // the callback on |*this|, so the callback will not outlive
+      // the object.
+      &CookieMonster::DeleteCanonicalCookie, base::Unretained(this), cookie,
+      std::move(callback)));
 }
 
 void CookieMonster::DeleteAllCreatedBetweenAsync(const Time& delete_begin,
                                                  const Time& delete_end,
                                                  DeleteCallback callback) {
-  scoped_refptr<DeleteAllCreatedBetweenTask> task =
-      new DeleteAllCreatedBetweenTask(this, delete_begin, delete_end,
-                                      std::move(callback));
-
-  DoCookieTask(task);
+  DoCookieCallback(base::BindOnce(
+      // base::Unretained is safe as DoCookieCallbackForURL stores
+      // the callback on |*this|, so the callback will not outlive
+      // the object.
+      &CookieMonster::DeleteAllCreatedBetween, base::Unretained(this),
+      delete_begin, delete_end, std::move(callback)));
 }
 
 void CookieMonster::DeleteAllCreatedBetweenWithPredicateAsync(
@@ -1031,21 +578,27 @@
     const base::Callback<bool(const CanonicalCookie&)>& predicate,
     DeleteCallback callback) {
   if (predicate.is_null()) {
-    std::move(callback).Run(0);
+    MaybeRunCookieCallback(std::move(callback), 0u);
     return;
   }
-  scoped_refptr<DeleteAllCreatedBetweenWithPredicateTask> task =
-      new DeleteAllCreatedBetweenWithPredicateTask(
-          this, delete_begin, delete_end, predicate, std::move(callback));
-  DoCookieTask(task);
+
+  DoCookieCallback(base::BindOnce(
+      // base::Unretained is safe as DoCookieCallbackForURL stores
+      // the callback on |*this|, so the callback will not outlive
+      // the object.
+      &CookieMonster::DeleteAllCreatedBetweenWithPredicate,
+      base::Unretained(this), delete_begin, delete_end, predicate,
+      std::move(callback)));
 }
 
 void CookieMonster::DeleteSessionCookiesAsync(
     CookieStore::DeleteCallback callback) {
-  scoped_refptr<DeleteSessionCookiesTask> task =
-      new DeleteSessionCookiesTask(this, std::move(callback));
-
-  DoCookieTask(task);
+  DoCookieCallback(base::BindOnce(
+      // base::Unretained is safe as DoCookieCallbackForURL stores
+      // the callback on |*this|, so the callback will not outlive
+      // the object.
+      &CookieMonster::DeleteSessionCookies, base::Unretained(this),
+      std::move(callback)));
 }
 
 void CookieMonster::SetCookieableSchemes(
@@ -1109,7 +662,7 @@
   }
 }
 
-bool CookieMonster::SetCookieWithDetails(const GURL& url,
+void CookieMonster::SetCookieWithDetails(const GURL& url,
                                          const std::string& name,
                                          const std::string& value,
                                          const std::string& domain,
@@ -1120,27 +673,35 @@
                                          bool secure,
                                          bool http_only,
                                          CookieSameSite same_site,
-                                         CookiePriority priority) {
+                                         CookiePriority priority,
+                                         SetCookiesCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  if (!HasCookieableScheme(url))
-    return false;
+  if (!HasCookieableScheme(url)) {
+    MaybeRunCookieCallback(std::move(callback), false);
+    return;
+  }
 
   // Validate consistency of passed arguments.
   if (ParsedCookie::ParseTokenString(name) != name ||
       ParsedCookie::ParseValueString(value) != value ||
       ParsedCookie::ParseValueString(domain) != domain ||
       ParsedCookie::ParseValueString(path) != path) {
-    return false;
+    MaybeRunCookieCallback(std::move(callback), false);
+    return;
   }
 
   std::string cookie_domain;
-  if (!cookie_util::GetCookieDomainWithString(url, domain, &cookie_domain))
-    return false;
+  if (!cookie_util::GetCookieDomainWithString(url, domain, &cookie_domain)) {
+    MaybeRunCookieCallback(std::move(callback), false);
+    return;
+  }
 
   std::string cookie_path = CanonicalCookie::CanonPathWithString(url, path);
-  if (!path.empty() && cookie_path != path)
-    return false;
+  if (!path.empty() && cookie_path != path) {
+    MaybeRunCookieCallback(std::move(callback), false);
+    return;
+  }
 
   // Canonicalize path again to make sure it escapes characters as needed.
   url::Component path_component(0, cookie_path.length());
@@ -1155,10 +716,11 @@
       name, value, cookie_domain, cookie_path, creation_time, expiration_time,
       last_access_time, secure, http_only, same_site, priority));
 
-  return SetCanonicalCookie(std::move(cc), url.SchemeIsCryptographic(), true);
+  SetCanonicalCookie(std::move(cc), url.SchemeIsCryptographic(), true,
+                     std::move(callback));
 }
 
-CookieList CookieMonster::GetAllCookies() {
+void CookieMonster::GetAllCookies(GetCookieListCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   // This function is being called to scrape the cookie list for management UI
@@ -1185,32 +747,31 @@
   for (auto* cookie_ptr : cookie_ptrs)
     cookie_list.push_back(*cookie_ptr);
 
-  return cookie_list;
+  MaybeRunCookieCallback(std::move(callback), cookie_list);
 }
 
-CookieList CookieMonster::GetCookieListWithOptions(
-    const GURL& url,
-    const CookieOptions& options) {
+void CookieMonster::GetCookieListWithOptions(const GURL& url,
+                                             const CookieOptions& options,
+                                             GetCookieListCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   CookieList cookies;
-  if (!HasCookieableScheme(url))
-    return cookies;
+  if (HasCookieableScheme(url)) {
+    std::vector<CanonicalCookie*> cookie_ptrs;
+    FindCookiesForHostAndDomain(url, options, &cookie_ptrs);
+    std::sort(cookie_ptrs.begin(), cookie_ptrs.end(), CookieSorter);
 
-  std::vector<CanonicalCookie*> cookie_ptrs;
-  FindCookiesForHostAndDomain(url, options, &cookie_ptrs);
-  std::sort(cookie_ptrs.begin(), cookie_ptrs.end(), CookieSorter);
-
-  cookies.reserve(cookie_ptrs.size());
-  for (std::vector<CanonicalCookie*>::const_iterator it = cookie_ptrs.begin();
-       it != cookie_ptrs.end(); it++)
-    cookies.push_back(**it);
-
-  return cookies;
+    cookies.reserve(cookie_ptrs.size());
+    for (std::vector<CanonicalCookie*>::const_iterator it = cookie_ptrs.begin();
+         it != cookie_ptrs.end(); it++)
+      cookies.push_back(**it);
+  }
+  MaybeRunCookieCallback(std::move(callback), cookies);
 }
 
-uint32_t CookieMonster::DeleteAllCreatedBetween(const Time& delete_begin,
-                                                const Time& delete_end) {
+void CookieMonster::DeleteAllCreatedBetween(const Time& delete_begin,
+                                            const Time& delete_end,
+                                            DeleteCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   uint32_t num_deleted = 0;
@@ -1227,13 +788,17 @@
     }
   }
 
-  return num_deleted;
+  FlushStore(
+      base::BindOnce(&MayeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(),
+                     callback ? base::BindOnce(std::move(callback), num_deleted)
+                              : base::OnceClosure()));
 }
 
-uint32_t CookieMonster::DeleteAllCreatedBetweenWithPredicate(
+void CookieMonster::DeleteAllCreatedBetweenWithPredicate(
     const base::Time& delete_begin,
     const base::Time& delete_end,
-    const base::Callback<bool(const CanonicalCookie&)>& predicate) {
+    const base::Callback<bool(const CanonicalCookie&)>& predicate,
+    DeleteCallback callback) {
   uint32_t num_deleted = 0;
   for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) {
     CookieMap::iterator curit = it;
@@ -1251,45 +816,55 @@
     }
   }
 
-  return num_deleted;
+  FlushStore(
+      base::BindOnce(&MayeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(),
+                     callback ? base::BindOnce(std::move(callback), num_deleted)
+                              : base::OnceClosure()));
 }
 
-bool CookieMonster::SetCookieWithOptions(const GURL& url,
+void CookieMonster::SetCookieWithOptions(const GURL& url,
                                          const std::string& cookie_line,
-                                         const CookieOptions& options) {
+                                         const CookieOptions& options,
+                                         SetCookiesCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   if (!HasCookieableScheme(url)) {
-    return false;
+    MaybeRunCookieCallback(std::move(callback), false);
+    return;
   }
 
-  return SetCookieWithCreationTimeAndOptions(url, cookie_line, Time(), options);
+  SetCookieWithCreationTimeAndOptions(url, cookie_line, Time(), options,
+                                      std::move(callback));
 }
 
-std::string CookieMonster::GetCookiesWithOptions(const GURL& url,
-                                                 const CookieOptions& options) {
+void CookieMonster::GetCookiesWithOptions(const GURL& url,
+                                          const CookieOptions& options,
+                                          GetCookiesCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  if (!HasCookieableScheme(url))
-    return std::string();
+  std::string cookie_line;
+  if (HasCookieableScheme(url)) {
+    std::vector<CanonicalCookie*> cookies;
+    FindCookiesForHostAndDomain(url, options, &cookies);
+    std::sort(cookies.begin(), cookies.end(), CookieSorter);
 
-  std::vector<CanonicalCookie*> cookies;
-  FindCookiesForHostAndDomain(url, options, &cookies);
-  std::sort(cookies.begin(), cookies.end(), CookieSorter);
+    cookie_line = BuildCookieLine(cookies);
 
-  std::string cookie_line = BuildCookieLine(cookies);
-
-  VLOG(kVlogGetCookies) << "GetCookies() result: " << cookie_line;
-
-  return cookie_line;
+    VLOG(kVlogGetCookies) << "GetCookies() result: " << cookie_line;
+  }
+  MaybeRunCookieCallback(std::move(callback), cookie_line);
 }
 
 void CookieMonster::DeleteCookie(const GURL& url,
-                                 const std::string& cookie_name) {
+                                 const std::string& cookie_name,
+                                 base::OnceClosure callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  if (!HasCookieableScheme(url))
+  if (!HasCookieableScheme(url)) {
+    // TODO(rdsmith): Would be good to provide a failure indication here.
+    MaybeRunCookieCallback(std::move(callback));
     return;
+  }
 
   CookieOptions options;
   options.set_include_httponly();
@@ -1315,41 +890,57 @@
       InternalDeleteCookie(curit, true, DELETE_COOKIE_SINGLE);
     }
   }
+
+  FlushStore(base::BindOnce(&MayeRunDeleteCallback,
+                            weak_ptr_factory_.GetWeakPtr(),
+                            // No callback null check needed as BindOnce
+                            // is not being called and MaybeRunDeleteCallback
+                            // has its own check.
+                            std::move(callback)));
 }
 
-uint32_t CookieMonster::DeleteCanonicalCookie(const CanonicalCookie& cookie) {
+void CookieMonster::DeleteCanonicalCookie(const CanonicalCookie& cookie,
+                                          DeleteCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
+  uint32_t result = 0u;
   for (CookieMapItPair its = cookies_.equal_range(GetKey(cookie.Domain()));
        its.first != its.second; ++its.first) {
     // The creation date acts as the unique index...
     if (its.first->second->CreationDate() == cookie.CreationDate()) {
       InternalDeleteCookie(its.first, true, DELETE_COOKIE_CANONICAL);
-      return 1u;
+      result = 1u;
+      break;
     }
   }
-  return 0u;
+  FlushStore(
+      base::BindOnce(&MayeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(),
+                     callback ? base::BindOnce(std::move(callback), result)
+                              : base::OnceClosure()));
 }
 
-bool CookieMonster::SetCookieWithCreationTime(const GURL& url,
-                                              const std::string& cookie_line,
-                                              const base::Time& creation_time) {
+void CookieMonster::SetCookieWithCreationTimeForTesting(
+    const GURL& url,
+    const std::string& cookie_line,
+    const base::Time& creation_time,
+    SetCookiesCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
   DCHECK(!store_.get()) << "This method is only to be used by unit-tests.";
 
   if (!HasCookieableScheme(url)) {
-    return false;
+    MaybeRunCookieCallback(std::move(callback), false);
+    return;
   }
 
   MarkCookieStoreAsInitialized();
   if (ShouldFetchAllCookiesWhenFetchingAnyCookie())
     FetchAllCookiesIfNecessary();
 
-  return SetCookieWithCreationTimeAndOptions(url, cookie_line, creation_time,
-                                             CookieOptions());
+  return SetCookieWithCreationTimeAndOptions(
+      url, cookie_line, creation_time, CookieOptions(), std::move(callback));
 }
 
-uint32_t CookieMonster::DeleteSessionCookies() {
+void CookieMonster::DeleteSessionCookies(DeleteCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   uint32_t num_deleted = 0;
@@ -1365,7 +956,10 @@
     }
   }
 
-  return num_deleted;
+  FlushStore(
+      base::BindOnce(&MayeRunDeleteCallback, weak_ptr_factory_.GetWeakPtr(),
+                     callback ? base::BindOnce(std::move(callback), num_deleted)
+                              : base::OnceClosure()));
 }
 
 void CookieMonster::MarkCookieStoreAsInitialized() {
@@ -1440,11 +1034,9 @@
   // Run all tasks for the key. Note that running a task can result in multiple
   // tasks being added to the back of the deque.
   while (!tasks_pending_for_key->second.empty()) {
-    scoped_refptr<CookieMonsterTask> task =
-        tasks_pending_for_key->second.front();
+    base::OnceClosure task = std::move(tasks_pending_for_key->second.front());
     tasks_pending_for_key->second.pop_front();
-
-    task->Run();
+    std::move(task).Run();
   }
 
   tasks_pending_for_key_.erase(tasks_pending_for_key);
@@ -1524,16 +1116,17 @@
   // Needed to prevent any recursively queued tasks from going back into the
   // per-key queues.
   seen_global_task_ = true;
-  for (const auto& tasks_for_key : tasks_pending_for_key_) {
-    tasks_pending_.insert(tasks_pending_.begin(), tasks_for_key.second.begin(),
-                          tasks_for_key.second.end());
+  for (auto& tasks_for_key : tasks_pending_for_key_) {
+    tasks_pending_.insert(tasks_pending_.begin(),
+                          std::make_move_iterator(tasks_for_key.second.begin()),
+                          std::make_move_iterator(tasks_for_key.second.end()));
   }
   tasks_pending_for_key_.clear();
 
   while (!tasks_pending_.empty()) {
-    scoped_refptr<CookieMonsterTask> request_task = tasks_pending_.front();
+    base::OnceClosure request_task = std::move(tasks_pending_.front());
     tasks_pending_.pop_front();
-    request_task->Run();
+    std::move(request_task).Run();
   }
 
   DCHECK(tasks_pending_for_key_.empty());
@@ -1779,11 +1372,12 @@
   return inserted;
 }
 
-bool CookieMonster::SetCookieWithCreationTimeAndOptions(
+void CookieMonster::SetCookieWithCreationTimeAndOptions(
     const GURL& url,
     const std::string& cookie_line,
     const Time& creation_time_or_null,
-    const CookieOptions& options) {
+    const CookieOptions& options,
+    SetCookiesCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   VLOG(kVlogSetCookies) << "SetCookie() line: " << cookie_line;
@@ -1799,19 +1393,23 @@
 
   if (!cc.get()) {
     VLOG(kVlogSetCookies) << "WARNING: Failed to allocate CanonicalCookie";
-    return false;
+    MaybeRunCookieCallback(std::move(callback), false);
+    return;
   }
-  return SetCanonicalCookie(std::move(cc), url.SchemeIsCryptographic(),
-                            !options.exclude_httponly());
+  SetCanonicalCookie(std::move(cc), url.SchemeIsCryptographic(),
+                     !options.exclude_httponly(), std::move(callback));
 }
 
-bool CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
+void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
                                        bool secure_source,
-                                       bool modify_http_only) {
+                                       bool modify_http_only,
+                                       SetCookiesCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
-  if (cc->IsSecure() && !secure_source)
-    return false;
+  if (cc->IsSecure() && !secure_source) {
+    MaybeRunCookieCallback(std::move(callback), false);
+    return;
+  }
 
   const std::string key(GetKey(cc->Domain()));
 
@@ -1835,7 +1433,8 @@
         "insecure scheme";
 
     VLOG(kVlogSetCookies) << error;
-    return false;
+    MaybeRunCookieCallback(std::move(callback), false);
+    return;
   }
 
   VLOG(kVlogSetCookies) << "SetCookie() key: " << key
@@ -1877,11 +1476,42 @@
   // and we will purge the expired cookies in GetCookies().
   GarbageCollect(creation_date, key);
 
-  return true;
+  MaybeRunCookieCallback(std::move(callback), true);
 }
 
-bool CookieMonster::SetAllCookies(const CookieList& list) {
+void CookieMonster::SetAllCookies(CookieList list,
+                                  SetCookiesCallback callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
+  CookieList positive_diff;
+  CookieList negative_diff;
+
+  CookieList old_cookies;
+  old_cookies.reserve(cookies_.size());
+  for (const auto& cookie : cookies_)
+    old_cookies.push_back(*cookie.second.get());
+
+  ComputeCookieDiff(&old_cookies, &list, &positive_diff, &negative_diff);
+
+  for (const auto& cookie_to_delete : negative_diff) {
+    for (CookieMapItPair its =
+             cookies_.equal_range(GetKey(cookie_to_delete.Domain()));
+         its.first != its.second; ++its.first) {
+      // The creation date acts as the unique index...
+      if (its.first->second->CreationDate() ==
+          cookie_to_delete.CreationDate()) {
+        // TODO(rdsmith): DELETE_COOKIE_CANONICAL is incorrect and should
+        // be changed.
+        InternalDeleteCookie(its.first, true, DELETE_COOKIE_CANONICAL);
+        break;
+      }
+    }
+  }
+
+  if (positive_diff.size() == 0) {
+    MaybeRunCookieCallback(std::move(callback), true);
+    return;
+  }
+
   for (const auto& cookie : list) {
     const std::string key(GetKey(cookie.Domain()));
     Time creation_time = cookie.CreationDate();
@@ -1907,7 +1537,7 @@
   // shouldn't have a return value.  But it should also be deleted (see
   // https://codereview.chromium.org/2882063002/#msg64), which would
   // solve the return value problem.
-  return true;
+  MaybeRunCookieCallback(std::move(callback), true);
 }
 
 void CookieMonster::InternalUpdateCookieAccessTime(CanonicalCookie* cc,
@@ -2370,8 +2000,7 @@
                                    last_time_seen_.ToInternalValue() + 1));
 }
 
-void CookieMonster::DoCookieTask(
-    const scoped_refptr<CookieMonsterTask>& task_item) {
+void CookieMonster::DoCookieCallback(base::OnceClosure callback) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   MarkCookieStoreAsInitialized();
@@ -2379,16 +2008,15 @@
   seen_global_task_ = true;
 
   if (!finished_fetching_all_cookies_ && store_.get()) {
-    tasks_pending_.push_back(task_item);
+    tasks_pending_.push_back(std::move(callback));
     return;
   }
 
-  task_item->Run();
+  std::move(callback).Run();
 }
 
-void CookieMonster::DoCookieTaskForURL(
-    const scoped_refptr<CookieMonsterTask>& task_item,
-    const GURL& url) {
+void CookieMonster::DoCookieCallbackForURL(base::OnceClosure callback,
+                                           const GURL& url) {
   MarkCookieStoreAsInitialized();
   if (ShouldFetchAllCookiesWhenFetchingAnyCookie())
     FetchAllCookiesIfNecessary();
@@ -2401,31 +2029,29 @@
     // the global queue, |tasks_pending_| may be empty, which is why another
     // bool is needed.
     if (seen_global_task_) {
-      tasks_pending_.push_back(task_item);
+      tasks_pending_.push_back(std::move(callback));
       return;
     }
 
     // Checks if the domain key has been loaded.
     std::string key(cookie_util::GetEffectiveDomain(url.scheme(), url.host()));
     if (keys_loaded_.find(key) == keys_loaded_.end()) {
-      std::map<std::string,
-               std::deque<scoped_refptr<CookieMonsterTask>>>::iterator it =
+      std::map<std::string, std::deque<base::OnceClosure>>::iterator it =
           tasks_pending_for_key_.find(key);
       if (it == tasks_pending_for_key_.end()) {
         store_->LoadCookiesForKey(
             key, base::Bind(&CookieMonster::OnKeyLoaded,
                             weak_ptr_factory_.GetWeakPtr(), key));
         it = tasks_pending_for_key_
-                 .insert(std::make_pair(
-                     key, std::deque<scoped_refptr<CookieMonsterTask>>()))
+                 .insert(std::make_pair(key, std::deque<base::OnceClosure>()))
                  .first;
       }
-      it->second.push_back(task_item);
+      it->second.push_back(std::move(callback));
       return;
     }
   }
 
-  task_item->Run();
+  std::move(callback).Run();
 }
 
 void CookieMonster::ComputeCookieDiff(CookieList* old_cookies,
@@ -2463,11 +2089,6 @@
                       FullDiffCookieSorter);
 }
 
-void CookieMonster::RunCallback(base::OnceClosure callback) {
-  DCHECK(thread_checker_.CalledOnValidThread());
-  std::move(callback).Run();
-}
-
 void CookieMonster::RunCookieChangedCallbacks(const CanonicalCookie& cookie,
                                               ChangeCause cause) {
   DCHECK(thread_checker_.CalledOnValidThread());
diff --git a/net/cookies/cookie_monster.h b/net/cookies/cookie_monster.h
index 13ebf88..fe968dba 100644
--- a/net/cookies/cookie_monster.h
+++ b/net/cookies/cookie_monster.h
@@ -51,9 +51,9 @@
 //
 // A cookie task is either pending loading of the entire cookie store, or
 // loading of cookies for a specific domain key(eTLD+1). In the former case, the
-// cookie task will be queued in tasks_pending_ while PersistentCookieStore
+// cookie callback will be queued in tasks_pending_ while PersistentCookieStore
 // chain loads the cookie store on DB thread. In the latter case, the cookie
-// task will be queued in tasks_pending_for_key_ while PermanentCookieStore
+// callback will be queued in tasks_pending_for_key_ while PermanentCookieStore
 // loads cookies for the specified domain key(eTLD+1) on DB thread.
 //
 // TODO(deanm) Implement CookieMonster, the cookie database.
@@ -228,38 +228,17 @@
 
   bool IsEphemeral() override;
 
+  void SetCookieWithCreationTimeForTesting(const GURL& url,
+                                           const std::string& cookie_line,
+                                           const base::Time& creation_time,
+                                           SetCookiesCallback callback);
+
  private:
   CookieMonster(PersistentCookieStore* store,
                 CookieMonsterDelegate* delegate,
                 ChannelIDService* channel_id_service,
                 base::TimeDelta last_access_threshold);
 
-  // For queueing the cookie monster calls.
-  class CookieMonsterTask;
-  template <typename Result>
-  class DeleteTask;
-  class DeleteAllCreatedBetweenTask;
-  class DeleteAllCreatedBetweenWithPredicateTask;
-  class DeleteCookieTask;
-  class DeleteCanonicalCookieTask;
-  class GetCookieListForURLWithOptionsTask;
-  class GetAllCookiesTask;
-  class GetCookiesWithOptionsTask;
-  class GetCookieListWithOptionsTask;
-  class SetAllCookiesTask;
-  class SetCookieWithDetailsTask;
-  class SetCookieWithOptionsTask;
-  class SetCanonicalCookieTask;
-  class DeleteSessionCookiesTask;
-
-  // Testing support.
-  // For SetCookieWithCreationTime.
-  FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest,
-                           TestCookieDeleteAllCreatedBetweenTimestamps);
-  FRIEND_TEST_ALL_PREFIXES(
-      CookieMonsterTest,
-      TestCookieDeleteAllCreatedBetweenTimestampsWithPredicate);
-
   // For garbage collection constants.
   FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, TestHostGarbageCollection);
   FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, GarbageCollectionTriggers);
@@ -417,7 +396,7 @@
   // The following are synchronous calls to which the asynchronous methods
   // delegate either immediately (if the store is loaded) or through a deferred
   // task (if the store is not yet loaded).
-  bool SetCookieWithDetails(const GURL& url,
+  void SetCookieWithDetails(const GURL& url,
                             const std::string& name,
                             const std::string& value,
                             const std::string& domain,
@@ -428,47 +407,53 @@
                             bool secure,
                             bool http_only,
                             CookieSameSite same_site,
-                            CookiePriority priority);
+                            CookiePriority priority,
+                            SetCookiesCallback callback);
 
   // Sets a canonical cookie, deletes equivalents and performs garbage
   // collection.  |source_secure| indicates if the cookie is being set
   // from a secure source (e.g. a cryptographic scheme).
   // |modify_http_only| indicates if this setting operation is allowed
   // to affect http_only cookies.
-  bool SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cookie,
+  void SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cookie,
                           bool secure_source,
-                          bool can_modify_httponly);
+                          bool can_modify_httponly,
+                          SetCookiesCallback callback);
 
-  CookieList GetAllCookies();
+  void GetAllCookies(GetCookieListCallback callback);
 
-  CookieList GetCookieListWithOptions(const GURL& url,
-                                      const CookieOptions& options);
+  void GetCookieListWithOptions(const GURL& url,
+                                const CookieOptions& options,
+                                GetCookieListCallback callback);
 
-  uint32_t DeleteAllCreatedBetween(const base::Time& delete_begin,
-                                   const base::Time& delete_end);
+  void DeleteAllCreatedBetween(const base::Time& delete_begin,
+                               const base::Time& delete_end,
+                               DeleteCallback callback);
 
   // Predicate will be called with the calling thread.
-  uint32_t DeleteAllCreatedBetweenWithPredicate(
+  void DeleteAllCreatedBetweenWithPredicate(
       const base::Time& delete_begin,
       const base::Time& delete_end,
-      const base::Callback<bool(const CanonicalCookie&)>& predicate);
+      const base::Callback<bool(const CanonicalCookie&)>& predicate,
+      DeleteCallback callback);
 
-  bool SetCookieWithOptions(const GURL& url,
+  void SetCookieWithOptions(const GURL& url,
                             const std::string& cookie_line,
-                            const CookieOptions& options);
+                            const CookieOptions& options,
+                            SetCookiesCallback callback);
 
-  std::string GetCookiesWithOptions(const GURL& url,
-                                    const CookieOptions& options);
+  void GetCookiesWithOptions(const GURL& url,
+                             const CookieOptions& options,
+                             GetCookiesCallback callback);
 
-  void DeleteCookie(const GURL& url, const std::string& cookie_name);
+  void DeleteCookie(const GURL& url,
+                    const std::string& cookie_name,
+                    base::OnceClosure callback);
 
-  uint32_t DeleteCanonicalCookie(const CanonicalCookie& cookie);
+  void DeleteCanonicalCookie(const CanonicalCookie& cookie,
+                             DeleteCallback callback);
 
-  bool SetCookieWithCreationTime(const GURL& url,
-                                 const std::string& cookie_line,
-                                 const base::Time& creation_time);
-
-  uint32_t DeleteSessionCookies();
+  void DeleteSessionCookies(DeleteCallback callback);
 
   // The first access to the cookie store initializes it. This method should be
   // called before any access to the cookie store.
@@ -552,15 +537,16 @@
   // Helper function that sets cookies with more control.
   // Not exposed as we don't want callers to have the ability
   // to specify (potentially duplicate) creation times.
-  bool SetCookieWithCreationTimeAndOptions(const GURL& url,
+  void SetCookieWithCreationTimeAndOptions(const GURL& url,
                                            const std::string& cookie_line,
                                            const base::Time& creation_time,
-                                           const CookieOptions& options);
+                                           const CookieOptions& options,
+                                           SetCookiesCallback callback);
 
   // Sets all cookies from |list| after deleting any equivalent cookie.
   // For data gathering purposes, this routine is treated as if it is
   // restoring saved cookies; some statistics are not gathered in this case.
-  bool SetAllCookies(const CookieList& list);
+  void SetAllCookies(CookieList list, SetCookiesCallback callback);
 
   void InternalUpdateCookieAccessTime(CanonicalCookie* cc,
                                       const base::Time& current_time);
@@ -644,14 +630,13 @@
   // ugly and increment when we've seen the same time twice.
   base::Time CurrentTime();
 
-  // Runs the task if, or defers the task until, the full cookie database is
-  // loaded.
-  void DoCookieTask(const scoped_refptr<CookieMonsterTask>& task_item);
+  // Runs the callback if, or defers the callback until, the full cookie
+  // database is loaded.
+  void DoCookieCallback(base::OnceClosure callback);
 
-  // Runs the task if, or defers the task until, the cookies for the given URL
-  // are loaded.
-  void DoCookieTaskForURL(const scoped_refptr<CookieMonsterTask>& task_item,
-                          const GURL& url);
+  // Runs the callback if, or defers the callback until, the cookies for the
+  // given URL are loaded.
+  void DoCookieCallbackForURL(base::OnceClosure callback, const GURL& url);
 
   // Computes the difference between |old_cookies| and |new_cookies|, and writes
   // the result in |cookies_to_add| and |cookies_to_delete|.
@@ -663,10 +648,6 @@
                          CookieList* cookies_to_add,
                          CookieList* cookies_to_delete);
 
-  // Runs the given callback. Used to avoid running callbacks after the store
-  // has been destroyed.
-  void RunCallback(base::OnceClosure callback);
-
   // Run all cookie changed callbacks that are monitoring |cookie|.
   // |removed| is true if the cookie was deleted.
   void RunCookieChangedCallbacks(const CanonicalCookie& cookie,
@@ -699,16 +680,15 @@
   // Map of domain keys to their associated task queues. These tasks are blocked
   // until all cookies for the associated domain key eTLD+1 are loaded from the
   // backend store.
-  std::map<std::string, std::deque<scoped_refptr<CookieMonsterTask>>>
-      tasks_pending_for_key_;
+  std::map<std::string, std::deque<base::OnceClosure>> tasks_pending_for_key_;
 
   // Queues tasks that are blocked until all cookies are loaded from the backend
   // store.
-  std::deque<scoped_refptr<CookieMonsterTask>> tasks_pending_;
+  std::deque<base::OnceClosure> tasks_pending_;
 
   // Once a global cookie task has been seen, all per-key tasks must be put in
   // |tasks_pending_| instead of |tasks_pending_for_key_| to ensure a reasonable
-  // view of the cookie store. This more to ensure fancy cookie export/import
+  // view of the cookie store. This is more to ensure fancy cookie export/import
   // code has a consistent view of the CookieStore, rather than out of concern
   // for typical use.
   bool seen_global_task_;
diff --git a/net/cookies/cookie_monster_perftest.cc b/net/cookies/cookie_monster_perftest.cc
index ff951336..f723071 100644
--- a/net/cookies/cookie_monster_perftest.cc
+++ b/net/cookies/cookie_monster_perftest.cc
@@ -39,9 +39,9 @@
   std::unique_ptr<base::MessageLoop> message_loop_;
 };
 
-class BaseCallback {
+class CookieTestCallback {
  public:
-  BaseCallback() : has_run_(false) {}
+  CookieTestCallback() : has_run_(false) {}
 
  protected:
   void WaitForCallback() {
@@ -60,7 +60,7 @@
   bool has_run_;
 };
 
-class SetCookieCallback : public BaseCallback {
+class SetCookieCallback : public CookieTestCallback {
  public:
   void SetCookie(CookieMonster* cm,
                  const GURL& gurl,
@@ -74,12 +74,12 @@
  private:
   void Run(bool success) {
     EXPECT_TRUE(success);
-    BaseCallback::Run();
+    CookieTestCallback::Run();
   }
   CookieOptions options_;
 };
 
-class GetCookiesCallback : public BaseCallback {
+class GetCookiesCallback : public CookieTestCallback {
  public:
   const std::string& GetCookies(CookieMonster* cm, const GURL& gurl) {
     cm->GetCookiesWithOptionsAsync(
@@ -92,12 +92,29 @@
  private:
   void Run(const std::string& cookies) {
     cookies_ = cookies;
-    BaseCallback::Run();
+    CookieTestCallback::Run();
   }
   std::string cookies_;
   CookieOptions options_;
 };
 
+class GetAllCookiesCallback : public CookieTestCallback {
+ public:
+  CookieList GetAllCookies(CookieMonster* cm) {
+    cm->GetAllCookiesAsync(
+        base::Bind(&GetAllCookiesCallback::Run, base::Unretained(this)));
+    WaitForCallback();
+    return cookies_;
+  }
+
+ private:
+  void Run(const CookieList& cookies) {
+    cookies_ = cookies;
+    CookieTestCallback::Run();
+  }
+  CookieList cookies_;
+};
+
 }  // namespace
 
 TEST(ParsedCookieTest, TestParseCookies) {
@@ -227,7 +244,9 @@
         base::StringPrintf(domain_cookie_format_tree, it->c_str());
     setCookieCallback.SetCookie(cm.get(), gurl, cookie);
   }
-  EXPECT_EQ(31u, cm->GetAllCookies().size());
+
+  GetAllCookiesCallback getAllCookiesCallback;
+  EXPECT_EQ(31u, getAllCookiesCallback.GetAllCookies(cm.get()).size());
 
   GURL probe_gurl("https://b.a.b.a.top.com/");
   std::string cookie_line = getCookiesCallback.GetCookies(cm.get(), probe_gurl);
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc
index 5dd66bad..34c4888f 100644
--- a/net/cookies/cookie_monster_unittest.cc
+++ b/net/cookies/cookie_monster_unittest.cc
@@ -165,6 +165,20 @@
     return callback.result();
   }
 
+  bool SetCookieWithCreationTime(CookieMonster* cm,
+                                 const GURL& url,
+                                 const std::string& cookie_line,
+                                 base::Time creation_time) {
+    DCHECK(cm);
+    ResultSavingCookieCallback<bool> callback;
+    cm->SetCookieWithCreationTimeForTesting(
+        url, cookie_line, creation_time,
+        base::Bind(&ResultSavingCookieCallback<bool>::Run,
+                   base::Unretained(&callback)));
+    callback.WaitUntilDone();
+    return callback.result();
+  }
+
   uint32_t DeleteAllCreatedBetween(CookieMonster* cm,
                                    const base::Time& delete_begin,
                                    const base::Time& delete_end) {
@@ -1387,15 +1401,19 @@
 
   // Create 5 cookies with different creation dates.
   EXPECT_TRUE(
-      cm->SetCookieWithCreationTime(http_www_foo_.url(), "T-0=Now", now));
-  EXPECT_TRUE(cm->SetCookieWithCreationTime(
-      http_www_foo_.url(), "T-1=Yesterday", now - TimeDelta::FromDays(1)));
-  EXPECT_TRUE(cm->SetCookieWithCreationTime(
-      http_www_foo_.url(), "T-2=DayBefore", now - TimeDelta::FromDays(2)));
-  EXPECT_TRUE(cm->SetCookieWithCreationTime(
-      http_www_foo_.url(), "T-3=ThreeDays", now - TimeDelta::FromDays(3)));
-  EXPECT_TRUE(cm->SetCookieWithCreationTime(http_www_foo_.url(), "T-7=LastWeek",
-                                            now - TimeDelta::FromDays(7)));
+      SetCookieWithCreationTime(cm.get(), http_www_foo_.url(), "T-0=Now", now));
+  EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
+                                        "T-1=Yesterday",
+                                        now - TimeDelta::FromDays(1)));
+  EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
+                                        "T-2=DayBefore",
+                                        now - TimeDelta::FromDays(2)));
+  EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
+                                        "T-3=ThreeDays",
+                                        now - TimeDelta::FromDays(3)));
+  EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
+                                        "T-7=LastWeek",
+                                        now - TimeDelta::FromDays(7)));
 
   // Try to delete threedays and the daybefore.
   EXPECT_EQ(2u, DeleteAllCreatedBetween(cm.get(), now - TimeDelta::FromDays(3),
@@ -1436,15 +1454,19 @@
 
   // Create 5 cookies with different creation dates.
   EXPECT_TRUE(
-      cm->SetCookieWithCreationTime(http_www_foo_.url(), "T-0=Now", now));
-  EXPECT_TRUE(cm->SetCookieWithCreationTime(
-      http_www_foo_.url(), "T-1=Yesterday", now - TimeDelta::FromDays(1)));
-  EXPECT_TRUE(cm->SetCookieWithCreationTime(
-      http_www_foo_.url(), "T-2=DayBefore", now - TimeDelta::FromDays(2)));
-  EXPECT_TRUE(cm->SetCookieWithCreationTime(
-      http_www_foo_.url(), "T-3=ThreeDays", now - TimeDelta::FromDays(3)));
-  EXPECT_TRUE(cm->SetCookieWithCreationTime(http_www_foo_.url(), "T-7=LastWeek",
-                                            now - TimeDelta::FromDays(7)));
+      SetCookieWithCreationTime(cm.get(), http_www_foo_.url(), "T-0=Now", now));
+  EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
+                                        "T-1=Yesterday",
+                                        now - TimeDelta::FromDays(1)));
+  EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
+                                        "T-2=DayBefore",
+                                        now - TimeDelta::FromDays(2)));
+  EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
+                                        "T-3=ThreeDays",
+                                        now - TimeDelta::FromDays(3)));
+  EXPECT_TRUE(SetCookieWithCreationTime(cm.get(), http_www_foo_.url(),
+                                        "T-7=LastWeek",
+                                        now - TimeDelta::FromDays(7)));
 
   // Try to delete threedays and the daybefore, but we should do nothing due
   // to the predicate.
diff --git a/net/log/file_net_log_observer.cc b/net/log/file_net_log_observer.cc
index 7f78c9f..40100aad 100644
--- a/net/log/file_net_log_observer.cc
+++ b/net/log/file_net_log_observer.cc
@@ -43,6 +43,36 @@
        base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
 }
 
+// Opens |path| in write mode. Returns the file handle on success, or nullptr on
+// failure.
+base::ScopedFILE OpenFileForWrite(const base::FilePath& path) {
+  base::ScopedFILE result(base::OpenFile(path, "w"));
+  LOG_IF(ERROR, !result) << "Failed opening: " << path.value();
+  return result;
+}
+
+// Helper to write data to a file. The |file| handle may optionally be null, in
+// which case nothing will be written. Returns the number of bytes successfully
+// written (may be less than input data in case of errors).
+size_t WriteToFile(const base::ScopedFILE& file,
+                   base::StringPiece data1,
+                   base::StringPiece data2 = base::StringPiece(),
+                   base::StringPiece data3 = base::StringPiece()) {
+  size_t bytes_written = 0;
+
+  if (file) {
+    // Append each of data1, data2 and data3.
+    if (!data1.empty())
+      bytes_written += fwrite(data1.data(), 1, data1.size(), file.get());
+    if (!data2.empty())
+      bytes_written += fwrite(data2.data(), 1, data2.size(), file.get());
+    if (!data3.empty())
+      bytes_written += fwrite(data3.data(), 1, data3.size(), file.get());
+  }
+
+  return bytes_written;
+}
+
 }  // namespace
 
 namespace net {
@@ -173,7 +203,8 @@
   void IncrementCurrentFile();
 
   // Each ScopedFILE points to a netlog event file with the file name
-  // "event_file_<index>.json".
+  // "event_file_<index>.json". Consumers must verify that entries are non-null
+  // before using them.
   std::vector<base::ScopedFILE> event_files_;
 
   // The directory where the netlog files are created.
@@ -407,11 +438,13 @@
     std::unique_ptr<base::Value> constants_value) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
-  event_files_[current_file_idx_] = base::ScopedFILE(
-      base::OpenFile(directory_.AppendASCII("event_file_0.json"), "w"));
+  // Failure opening the file will result in null entries - consumers are
+  // responsible for checking.
+  event_files_[current_file_idx_] =
+      OpenFileForWrite(directory_.AppendASCII("event_file_0.json"));
 
-  base::ScopedFILE constants_file(
-      base::OpenFile(directory_.AppendASCII("constants.json"), "w"));
+  base::ScopedFILE constants_file =
+      OpenFileForWrite(directory_.AppendASCII("constants.json"));
 
   // Print constants to file and open events array.
   std::string json;
@@ -419,26 +452,26 @@
   // It should always be possible to convert constants to JSON.
   if (!base::JSONWriter::Write(*constants_value, &json))
     DCHECK(false);
-  fprintf(constants_file.get(), "{\"constants\":%s,\n\"events\": [\n",
-          json.c_str());
+  WriteToFile(constants_file, "{\"constants\":", json, ",\n\"events\": [\n");
 }
 
 void FileNetLogObserver::BoundedFileWriter::Stop(
     std::unique_ptr<base::Value> polled_data) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
-  base::ScopedFILE closing_file(
-      base::OpenFile(directory_.AppendASCII("end_netlog.json"), "w"));
+  base::ScopedFILE closing_file =
+      OpenFileForWrite(directory_.AppendASCII("end_netlog.json"));
 
   std::string json;
   if (polled_data)
     base::JSONWriter::Write(*polled_data, &json);
 
-  fprintf(closing_file.get(), "]%s}\n",
-          json.empty() ? "" : (",\n\"polledData\": " + json + "\n").c_str());
+  WriteToFile(closing_file, "]");
+  if (!json.empty())
+    WriteToFile(closing_file, ",\n\"polledData\": ", json, "\n");
+  WriteToFile(closing_file, "}\n");
 
-  // Flush all fprintfs to disk so that files can be safely accessed on
-  // callback.
+  // Flush all writes to disk so that files can be safely accessed on callback.
   event_files_.clear();
 }
 
@@ -448,10 +481,8 @@
   current_file_idx_++;
   current_file_idx_ %= total_num_files_;
   event_files_[current_file_idx_].reset();
-  event_files_[current_file_idx_] = base::ScopedFILE(base::OpenFile(
-      directory_.AppendASCII("event_file_" +
-                             base::SizeTToString(current_file_idx_) + ".json"),
-      "w"));
+  event_files_[current_file_idx_] = OpenFileForWrite(directory_.AppendASCII(
+      "event_file_" + base::SizeTToString(current_file_idx_) + ".json"));
 }
 
 void FileNetLogObserver::BoundedFileWriter::Flush(
@@ -463,8 +494,9 @@
 
   std::string to_print;
   CHECK(!event_files_.empty());
-  size_t file_size = ftell(event_files_[current_file_idx_].get());
-  size_t memory_freed = 0;
+  size_t file_size = event_files_[current_file_idx_]
+                         ? ftell(event_files_[current_file_idx_].get())
+                         : 0;
 
   while (!local_file_queue.empty()) {
     if (file_size >= max_file_size_) {
@@ -472,10 +504,8 @@
       IncrementCurrentFile();
       file_size = 0;
     }
-    fprintf(event_files_[current_file_idx_].get(), "%s,\n",
-            local_file_queue.front().get()->c_str());
-    file_size += local_file_queue.front()->size();
-    memory_freed += local_file_queue.front()->size();
+    file_size += WriteToFile(event_files_[current_file_idx_],
+                             *local_file_queue.front(), ",\n");
     local_file_queue.pop();
   }
 }
@@ -507,7 +537,7 @@
     std::unique_ptr<base::Value> constants_value) {
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
-  file_.reset(base::OpenFile(file_path_, "w"));
+  file_ = OpenFileForWrite(file_path_);
   first_event_written_ = false;
 
   // Print constants to file and open events array.
@@ -516,7 +546,7 @@
   // It should always be possible to convert constants to JSON.
   if (!base::JSONWriter::Write(*constants_value, &json))
     DCHECK(false);
-  fprintf(file_.get(), "{\"constants\":%s,\n\"events\": [\n", json.c_str());
+  WriteToFile(file_, "{\"constants\":", json, ",\n\"events\": [\n");
 }
 
 void FileNetLogObserver::UnboundedFileWriter::Stop(
@@ -527,10 +557,12 @@
   if (polled_data)
     base::JSONWriter::Write(*polled_data, &json);
 
-  fprintf(file_.get(), "]%s}\n",
-          json.empty() ? "" : (",\n\"polledData\": " + json + "\n").c_str());
+  WriteToFile(file_, "]");
+  if (!json.empty())
+    WriteToFile(file_, ",\n\"polledData\": ", json, "\n");
+  WriteToFile(file_, "}\n");
 
-  // Flush all fprintfs to disk so that the file can be safely accessed on
+  // Flush all writes to disk so that the file can be safely accessed on
   // callback.
   file_.reset();
 }
@@ -544,11 +576,11 @@
 
   while (!local_file_queue.empty()) {
     if (first_event_written_) {
-      fputs(",\n", file_.get());
+      WriteToFile(file_, ",\n");
     } else {
       first_event_written_ = true;
     }
-    fputs(local_file_queue.front()->c_str(), file_.get());
+    WriteToFile(file_, *local_file_queue.front());
     local_file_queue.pop();
   }
 }
diff --git a/net/log/file_net_log_observer.h b/net/log/file_net_log_observer.h
index 747b76a2..004b2763 100644
--- a/net/log/file_net_log_observer.h
+++ b/net/log/file_net_log_observer.h
@@ -47,7 +47,8 @@
  public:
   // Creates a FileNetLogObserver in bounded mode.
   //
-  // |directory| is the directory where the log files will be written to.
+  // |directory| is the directory where the log files will be written to. The
+  // directory must already exist.
   //
   // |max_total_size| is the approximate limit on the cumulative size of all
   // netlog files.
@@ -66,7 +67,8 @@
 
   // Creates a FileNetLogObserver in unbounded mode.
   //
-  // |log_path| is where the log file will be written to.
+  // |log_path| is where the log file will be written to. If a file already
+  // exists at this path it will be overwritten.
   //
   // |constants| is an optional legend for decoding constant values used in
   // the log. It should generally be a modified version of GetNetConstants().
diff --git a/net/log/file_net_log_observer_unittest.cc b/net/log/file_net_log_observer_unittest.cc
index 75082a766..af68ee8 100644
--- a/net/log/file_net_log_observer_unittest.cc
+++ b/net/log/file_net_log_observer_unittest.cc
@@ -11,6 +11,7 @@
 #include <utility>
 #include <vector>
 
+#include "base/files/file_enumerator.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/files/scoped_file.h"
@@ -158,19 +159,22 @@
  public:
   void SetUp() override {
     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
-    bounded_log_dir_ = temp_dir_.GetPath();
-    unbounded_log_path_ = bounded_log_dir_.AppendASCII("net-log.json");
+    if (IsBounded()) {
+      log_path_ = temp_dir_.GetPath();
+    } else {
+      log_path_ = temp_dir_.GetPath().AppendASCII("net-log.json");
+    }
   }
 
+  bool IsBounded() const { return GetParam(); }
+
   void CreateAndStartObserving(std::unique_ptr<base::Value> constants) {
-    bool bounded = GetParam();
-    if (bounded) {
+    if (IsBounded()) {
       logger_ = FileNetLogObserver::CreateBounded(
-          bounded_log_dir_, kLargeFileSize, kTotalNumFiles,
-          std::move(constants));
+          log_path_, kLargeFileSize, kTotalNumFiles, std::move(constants));
     } else {
-      logger_ = FileNetLogObserver::CreateUnbounded(unbounded_log_path_,
-                                                    std::move(constants));
+      logger_ =
+          FileNetLogObserver::CreateUnbounded(log_path_, std::move(constants));
     }
 
     logger_->StartObserving(&net_log_, NetLogCaptureMode::Default());
@@ -179,12 +183,11 @@
   ::testing::AssertionResult ReadNetLogFromDisk(
       std::unique_ptr<base::Value>* root,
       base::ListValue** events) {
-    bool bounded = GetParam();
     std::string input;
-    if (bounded) {
-      ReadBoundedLogFiles(bounded_log_dir_, &input);
+    if (IsBounded()) {
+      ReadBoundedLogFiles(log_path_, &input);
     } else {
-      base::ReadFileToString(unbounded_log_path_, &input);
+      base::ReadFileToString(log_path_, &input);
     }
     return ParseNetLogString(input, root, events);
   }
@@ -195,30 +198,26 @@
     // checking if they exist.
     base::TaskScheduler::GetInstance()->FlushForTesting();
 
-    bool bounded = GetParam();
-    if (bounded) {
-      if (base::PathExists(bounded_log_dir_.AppendASCII("constants.json")) ||
-          base::PathExists(bounded_log_dir_.AppendASCII("end_netlog.json")))
+    if (IsBounded()) {
+      if (base::PathExists(log_path_.AppendASCII("constants.json")) ||
+          base::PathExists(log_path_.AppendASCII("end_netlog.json")))
         return true;
       for (int i = 0; i < kTotalNumFiles; i++) {
-        if (base::PathExists(bounded_log_dir_.AppendASCII(
+        if (base::PathExists(log_path_.AppendASCII(
                 "event_file_" + std::to_string(i) + ".json")))
           return true;
       }
       return false;
     } else {
-      return base::PathExists(unbounded_log_path_);
+      return base::PathExists(log_path_);
     }
   }
 
  protected:
   NetLog net_log_;
   std::unique_ptr<FileNetLogObserver> logger_;
-
- private:
   base::ScopedTempDir temp_dir_;
-  base::FilePath bounded_log_dir_;
-  base::FilePath unbounded_log_path_;
+  base::FilePath log_path_;
 };
 
 // Used for tests that are exclusive to the bounded mode of FileNetLogObserver.
@@ -250,6 +249,14 @@
                                         ".json");
   }
 
+  base::FilePath GetEndNetlogPath() const {
+    return bounded_log_dir_.AppendASCII("end_netlog.json");
+  }
+
+  base::FilePath GetConstantsPath() const {
+    return bounded_log_dir_.AppendASCII("constants.json");
+  }
+
   static int64_t GetFileSize(const base::FilePath& path) {
     int64_t file_size;
     EXPECT_TRUE(base::GetFileSize(path, &file_size));
@@ -259,10 +266,10 @@
  protected:
   NetLog net_log_;
   std::unique_ptr<FileNetLogObserver> logger_;
+  base::FilePath bounded_log_dir_;
 
  private:
   base::ScopedTempDir temp_dir_;
-  base::FilePath bounded_log_dir_;
 };
 
 // Instantiates each FileNetLogObserverTest to use bounded and unbounded modes.
@@ -305,6 +312,29 @@
   ASSERT_TRUE(LogFilesExist());
 }
 
+// Tests creating a FileNetLogObserver using an invalid (can't be written to)
+// path.
+TEST_P(FileNetLogObserverTest, InitLogWithInvalidPath) {
+  // Use a path to a non-existent directory.
+  log_path_ = temp_dir_.GetPath().AppendASCII("bogus").AppendASCII("path");
+
+  CreateAndStartObserving(nullptr);
+
+  // Send dummy event
+  AddEntries(logger_.get(), 1, kDummyEventSize);
+
+  // No log files should have been written, as the log writer will not create
+  // missing directories.
+  ASSERT_FALSE(LogFilesExist());
+
+  logger_->StopObserving(nullptr, base::OnceClosure());
+
+  logger_.reset();
+
+  // There should still be no files.
+  ASSERT_FALSE(LogFilesExist());
+}
+
 TEST_P(FileNetLogObserverTest, GeneratesValidJSONWithNoEvents) {
   TestClosure closure;
 
@@ -809,6 +839,69 @@
   }
 }
 
+// Start logging in bounded mode. Create directories in places where the logger
+// expects to create files, in order to cause that file creation to fail.
+//
+//   constants.json      -- succeess
+//   event_file_0.json   -- fails to open
+//   end_netlog.json     -- fails to open
+TEST_F(FileNetLogObserverBoundedTest, SomeFilesFailToOpen) {
+  // The total size of events is equal to the total size of all files.
+  // |kEventSize| * |kNumEvents| = |kTotalFileSize|
+  const int kTotalFileSize = 10000;
+  const int kEventSize = 200;
+  const int kFileSize = kTotalFileSize / kTotalNumFiles;
+  const int kNumEvents = kTotalNumFiles * ((kFileSize - 1) / kEventSize + 1);
+  TestClosure closure;
+
+  // Create directories as a means to block files from being created by logger.
+  EXPECT_TRUE(base::CreateDirectory(GetEventFilePath(0)));
+  EXPECT_TRUE(base::CreateDirectory(GetEndNetlogPath()));
+
+  CreateAndStartObserving(nullptr, kTotalFileSize, kTotalNumFiles);
+
+  AddEntries(logger_.get(), kNumEvents, kEventSize);
+
+  logger_->StopObserving(nullptr, closure.closure());
+
+  closure.WaitForResult();
+
+  // Verify that the log directory only contains 3 files -- the
+  // original directories we created to block file creation, plus events.json.
+  base::FileEnumerator log_files(
+      bounded_log_dir_, /*recursive=*/true,
+      base::FileEnumerator::FILES | base::FileEnumerator::DIRECTORIES);
+
+  int matched_files = 0;
+  for (base::FilePath name = log_files.Next(); !name.empty();
+       name = log_files.Next()) {
+    // Either constants.json
+    if (name == GetConstantsPath()) {
+      matched_files++;
+      EXPECT_FALSE(log_files.GetInfo().IsDirectory());
+      continue;
+    }
+
+    // Or event_file_0.json
+    if (name == GetEventFilePath(0)) {
+      matched_files++;
+      EXPECT_TRUE(log_files.GetInfo().IsDirectory());
+      continue;
+    }
+
+    // Or end_netlog.json
+    if (name == GetEndNetlogPath()) {
+      matched_files++;
+      EXPECT_TRUE(log_files.GetInfo().IsDirectory());
+      continue;
+    }
+
+    ADD_FAILURE() << "Unexpected file: " << name.value();
+  }
+
+  EXPECT_EQ(3, matched_files);
+}
+
 void AddEntriesViaNetLog(NetLog* net_log, int num_entries) {
   for (int i = 0; i < num_entries; i++) {
     net_log->AddGlobalEntry(NetLogEventType::PAC_JAVASCRIPT_ERROR);
diff --git a/net/quic/chromium/quic_chromium_client_session_peer.cc b/net/quic/chromium/quic_chromium_client_session_peer.cc
index b1a6b14..4c633138 100644
--- a/net/quic/chromium/quic_chromium_client_session_peer.cc
+++ b/net/quic/chromium/quic_chromium_client_session_peer.cc
@@ -18,13 +18,6 @@
 }
 
 // static
-void QuicChromiumClientSessionPeer::SetChannelIDSent(
-    QuicChromiumClientSession* session,
-    bool channel_id_sent) {
-  session->crypto_stream_->channel_id_sent_ = channel_id_sent;
-}
-
-// static
 void QuicChromiumClientSessionPeer::SetHostname(
     QuicChromiumClientSession* session,
     const std::string& hostname) {
diff --git a/net/quic/chromium/quic_chromium_client_session_peer.h b/net/quic/chromium/quic_chromium_client_session_peer.h
index 39dbb8a..70f9bd7 100644
--- a/net/quic/chromium/quic_chromium_client_session_peer.h
+++ b/net/quic/chromium/quic_chromium_client_session_peer.h
@@ -24,9 +24,6 @@
                                 size_t max_streams,
                                 size_t default_streams);
 
-  static void SetChannelIDSent(QuicChromiumClientSession* session,
-                               bool channel_id_sent);
-
   static void SetHostname(QuicChromiumClientSession* session,
                           const std::string& hostname);
 
diff --git a/net/quic/chromium/quic_chromium_client_session_test.cc b/net/quic/chromium/quic_chromium_client_session_test.cc
index 4fd2b39e4..cadd9b50 100644
--- a/net/quic/chromium/quic_chromium_client_session_test.cc
+++ b/net/quic/chromium/quic_chromium_client_session_test.cc
@@ -58,6 +58,26 @@
 const uint16_t kServerPort = 443;
 const size_t kMaxReadersPerQuicSession = 5;
 
+// A subclass of QuicChromiumClientSession with GetSSLInfo overriden to allow
+// forcing the value of SSLInfo::channel_id_sent to true.
+class TestingQuicChromiumClientSession : public QuicChromiumClientSession {
+ public:
+  using QuicChromiumClientSession::QuicChromiumClientSession;
+
+  bool GetSSLInfo(SSLInfo* ssl_info) const override {
+    bool ret = QuicChromiumClientSession::GetSSLInfo(ssl_info);
+    if (ret)
+      ssl_info->channel_id_sent =
+          ssl_info->channel_id_sent || force_channel_id_sent_;
+    return ret;
+  }
+
+  void OverrideChannelIDSent() { force_channel_id_sent_ = true; }
+
+ private:
+  bool force_channel_id_sent_ = false;
+};
+
 class QuicChromiumClientSessionTest
     : public ::testing::TestWithParam<QuicVersion> {
  protected:
@@ -97,7 +117,7 @@
         0, QuicSocketAddress(QuicSocketAddressImpl(kIpEndPoint)), &helper_,
         &alarm_factory_, writer, true, Perspective::IS_CLIENT,
         SupportedVersions(GetParam()));
-    session_.reset(new QuicChromiumClientSession(
+    session_.reset(new TestingQuicChromiumClientSession(
         connection, std::move(socket),
         /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
         &transport_security_state_,
@@ -159,7 +179,7 @@
   MockCryptoClientStreamFactory crypto_client_stream_factory_;
   QuicClientPushPromiseIndex push_promise_index_;
   QuicServerId server_id_;
-  std::unique_ptr<QuicChromiumClientSession> session_;
+  std::unique_ptr<TestingQuicChromiumClientSession> session_;
   TestServerPushDelegate test_push_delegate_;
   QuicConnectionVisitorInterface* visitor_;
   TestCompletionCallback callback_;
@@ -976,7 +996,7 @@
   CompleteCryptoHandshake();
   session_->OnProofVerifyDetailsAvailable(details);
   QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
-  QuicChromiumClientSessionPeer::SetChannelIDSent(session_.get(), true);
+  session_->OverrideChannelIDSent();
 
   EXPECT_TRUE(session_->CanPool("www.example.org", PRIVACY_MODE_DISABLED));
   EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
@@ -1012,7 +1032,7 @@
   CompleteCryptoHandshake();
   session_->OnProofVerifyDetailsAvailable(details);
   QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
-  QuicChromiumClientSessionPeer::SetChannelIDSent(session_.get(), true);
+  session_->OverrideChannelIDSent();
 
   EXPECT_FALSE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
 }
@@ -1044,7 +1064,7 @@
   CompleteCryptoHandshake();
   session_->OnProofVerifyDetailsAvailable(details);
   QuicChromiumClientSessionPeer::SetHostname(session_.get(), "www.example.org");
-  QuicChromiumClientSessionPeer::SetChannelIDSent(session_.get(), true);
+  session_->OverrideChannelIDSent();
 
   EXPECT_TRUE(session_->CanPool("mail.example.org", PRIVACY_MODE_DISABLED));
 }
diff --git a/net/quic/core/quic_crypto_client_stream.cc b/net/quic/core/quic_crypto_client_stream.cc
index d37087d..0f4a180 100644
--- a/net/quic/core/quic_crypto_client_stream.cc
+++ b/net/quic/core/quic_crypto_client_stream.cc
@@ -27,59 +27,59 @@
 QuicCryptoClientStreamBase::QuicCryptoClientStreamBase(QuicSession* session)
     : QuicCryptoStream(session) {}
 
-QuicCryptoClientStream::ChannelIDSourceCallbackImpl::
-    ChannelIDSourceCallbackImpl(QuicCryptoClientStream* stream)
-    : stream_(stream) {}
+QuicCryptoClientHandshaker::ChannelIDSourceCallbackImpl::
+    ChannelIDSourceCallbackImpl(QuicCryptoClientHandshaker* parent)
+    : parent_(parent) {}
 
-QuicCryptoClientStream::ChannelIDSourceCallbackImpl::
+QuicCryptoClientHandshaker::ChannelIDSourceCallbackImpl::
     ~ChannelIDSourceCallbackImpl() {}
 
-void QuicCryptoClientStream::ChannelIDSourceCallbackImpl::Run(
+void QuicCryptoClientHandshaker::ChannelIDSourceCallbackImpl::Run(
     std::unique_ptr<ChannelIDKey>* channel_id_key) {
-  if (stream_ == nullptr) {
+  if (parent_ == nullptr) {
     return;
   }
 
-  stream_->channel_id_key_ = std::move(*channel_id_key);
-  stream_->channel_id_source_callback_run_ = true;
-  stream_->channel_id_source_callback_ = nullptr;
-  stream_->DoHandshakeLoop(nullptr);
+  parent_->channel_id_key_ = std::move(*channel_id_key);
+  parent_->channel_id_source_callback_run_ = true;
+  parent_->channel_id_source_callback_ = nullptr;
+  parent_->DoHandshakeLoop(nullptr);
 
   // The ChannelIDSource owns this object and will delete it when this method
   // returns.
 }
 
-void QuicCryptoClientStream::ChannelIDSourceCallbackImpl::Cancel() {
-  stream_ = nullptr;
+void QuicCryptoClientHandshaker::ChannelIDSourceCallbackImpl::Cancel() {
+  parent_ = nullptr;
 }
 
-QuicCryptoClientStream::ProofVerifierCallbackImpl::ProofVerifierCallbackImpl(
-    QuicCryptoClientStream* stream)
-    : stream_(stream) {}
+QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::
+    ProofVerifierCallbackImpl(QuicCryptoClientHandshaker* parent)
+    : parent_(parent) {}
 
-QuicCryptoClientStream::ProofVerifierCallbackImpl::
+QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::
     ~ProofVerifierCallbackImpl() {}
 
-void QuicCryptoClientStream::ProofVerifierCallbackImpl::Run(
+void QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::Run(
     bool ok,
     const string& error_details,
     std::unique_ptr<ProofVerifyDetails>* details) {
-  if (stream_ == nullptr) {
+  if (parent_ == nullptr) {
     return;
   }
 
-  stream_->verify_ok_ = ok;
-  stream_->verify_error_details_ = error_details;
-  stream_->verify_details_ = std::move(*details);
-  stream_->proof_verify_callback_ = nullptr;
-  stream_->DoHandshakeLoop(nullptr);
+  parent_->verify_ok_ = ok;
+  parent_->verify_error_details_ = error_details;
+  parent_->verify_details_ = std::move(*details);
+  parent_->proof_verify_callback_ = nullptr;
+  parent_->DoHandshakeLoop(nullptr);
 
   // The ProofVerifier owns this object and will delete it when this method
   // returns.
 }
 
-void QuicCryptoClientStream::ProofVerifierCallbackImpl::Cancel() {
-  stream_ = nullptr;
+void QuicCryptoClientHandshaker::ProofVerifierCallbackImpl::Cancel() {
+  parent_ = nullptr;
 }
 
 QuicCryptoClientStream::QuicCryptoClientStream(
@@ -88,7 +88,66 @@
     ProofVerifyContext* verify_context,
     QuicCryptoClientConfig* crypto_config,
     ProofHandler* proof_handler)
-    : QuicCryptoClientStreamBase(session),
+    : QuicCryptoClientStreamBase(session) {
+  DCHECK_EQ(Perspective::IS_CLIENT, session->connection()->perspective());
+  handshaker_.reset(new QuicCryptoClientHandshaker(
+      server_id, this, session, verify_context, crypto_config, proof_handler));
+}
+
+QuicCryptoClientStream::~QuicCryptoClientStream() {}
+
+bool QuicCryptoClientStream::CryptoConnect() {
+  return handshaker_->CryptoConnect();
+}
+
+int QuicCryptoClientStream::num_sent_client_hellos() const {
+  return handshaker_->num_sent_client_hellos();
+}
+
+int QuicCryptoClientStream::num_scup_messages_received() const {
+  return handshaker_->num_scup_messages_received();
+}
+
+bool QuicCryptoClientStream::encryption_established() const {
+  return handshaker_->encryption_established();
+}
+
+bool QuicCryptoClientStream::handshake_confirmed() const {
+  return handshaker_->handshake_confirmed();
+}
+
+const QuicCryptoNegotiatedParameters&
+QuicCryptoClientStream::crypto_negotiated_params() const {
+  return handshaker_->crypto_negotiated_params();
+}
+
+void QuicCryptoClientStream::OnHandshakeMessage(
+    const CryptoHandshakeMessage& message) {
+  QuicCryptoClientStreamBase::OnHandshakeMessage(message);
+  handshaker_->OnHandshakeMessage(message);
+}
+
+bool QuicCryptoClientStream::WasChannelIDSent() const {
+  return handshaker_->WasChannelIDSent();
+}
+
+bool QuicCryptoClientStream::WasChannelIDSourceCallbackRun() const {
+  return handshaker_->WasChannelIDSourceCallbackRun();
+}
+
+string QuicCryptoClientStream::chlo_hash() const {
+  return handshaker_->chlo_hash();
+}
+
+QuicCryptoClientHandshaker::QuicCryptoClientHandshaker(
+    const QuicServerId& server_id,
+    QuicCryptoClientStream* stream,
+    QuicSession* session,
+    ProofVerifyContext* verify_context,
+    QuicCryptoClientConfig* crypto_config,
+    QuicCryptoClientStream::ProofHandler* proof_handler)
+    : stream_(stream),
+      session_(session),
       next_state_(STATE_IDLE),
       num_client_hellos_(0),
       crypto_config_(crypto_config),
@@ -105,11 +164,9 @@
       num_scup_messages_received_(0),
       encryption_established_(false),
       handshake_confirmed_(false),
-      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {
-  DCHECK_EQ(Perspective::IS_CLIENT, session->connection()->perspective());
-}
+      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {}
 
-QuicCryptoClientStream::~QuicCryptoClientStream() {
+QuicCryptoClientHandshaker::~QuicCryptoClientHandshaker() {
   if (channel_id_source_callback_) {
     channel_id_source_callback_->Cancel();
   }
@@ -118,14 +175,13 @@
   }
 }
 
-void QuicCryptoClientStream::OnHandshakeMessage(
+void QuicCryptoClientHandshaker::OnHandshakeMessage(
     const CryptoHandshakeMessage& message) {
-  QuicCryptoClientStreamBase::OnHandshakeMessage(message);
-
   if (message.tag() == kSCUP) {
     if (!handshake_confirmed()) {
-      CloseConnectionWithDetails(QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE,
-                                 "Early SCUP disallowed");
+      stream_->CloseConnectionWithDetails(
+          QUIC_CRYPTO_UPDATE_BEFORE_HANDSHAKE_COMPLETE,
+          "Early SCUP disallowed");
       return;
     }
 
@@ -138,51 +194,55 @@
 
   // Do not process handshake messages after the handshake is confirmed.
   if (handshake_confirmed()) {
-    CloseConnectionWithDetails(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
-                               "Unexpected handshake message");
+    stream_->CloseConnectionWithDetails(
+        QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
+        "Unexpected handshake message");
     return;
   }
 
   DoHandshakeLoop(&message);
 }
 
-bool QuicCryptoClientStream::CryptoConnect() {
+bool QuicCryptoClientHandshaker::CryptoConnect() {
   next_state_ = STATE_INITIALIZE;
   DoHandshakeLoop(nullptr);
   return session()->connection()->connected();
 }
 
-int QuicCryptoClientStream::num_sent_client_hellos() const {
+int QuicCryptoClientHandshaker::num_sent_client_hellos() const {
   return num_client_hellos_;
 }
 
-int QuicCryptoClientStream::num_scup_messages_received() const {
+int QuicCryptoClientHandshaker::num_scup_messages_received() const {
   return num_scup_messages_received_;
 }
 
-// Used in Chromium, but not in the server.
-bool QuicCryptoClientStream::WasChannelIDSent() const {
+bool QuicCryptoClientHandshaker::WasChannelIDSent() const {
   return channel_id_sent_;
 }
 
-bool QuicCryptoClientStream::WasChannelIDSourceCallbackRun() const {
+bool QuicCryptoClientHandshaker::WasChannelIDSourceCallbackRun() const {
   return channel_id_source_callback_run_;
 }
 
-bool QuicCryptoClientStream::encryption_established() const {
+string QuicCryptoClientHandshaker::chlo_hash() const {
+  return chlo_hash_;
+}
+
+bool QuicCryptoClientHandshaker::encryption_established() const {
   return encryption_established_;
 }
 
-bool QuicCryptoClientStream::handshake_confirmed() const {
+bool QuicCryptoClientHandshaker::handshake_confirmed() const {
   return handshake_confirmed_;
 }
 
 const QuicCryptoNegotiatedParameters&
-QuicCryptoClientStream::crypto_negotiated_params() const {
+QuicCryptoClientHandshaker::crypto_negotiated_params() const {
   return *crypto_negotiated_params_;
 }
 
-void QuicCryptoClientStream::HandleServerConfigUpdateMessage(
+void QuicCryptoClientHandshaker::HandleServerConfigUpdateMessage(
     const CryptoHandshakeMessage& server_config_update) {
   DCHECK(server_config_update.tag() == kSCUP);
   string error_details;
@@ -194,7 +254,7 @@
       crypto_negotiated_params_, &error_details);
 
   if (error != QUIC_NO_ERROR) {
-    CloseConnectionWithDetails(
+    stream_->CloseConnectionWithDetails(
         error, "Server config update invalid: " + error_details);
     return;
   }
@@ -207,7 +267,8 @@
   DoHandshakeLoop(nullptr);
 }
 
-void QuicCryptoClientStream::DoHandshakeLoop(const CryptoHandshakeMessage* in) {
+void QuicCryptoClientHandshaker::DoHandshakeLoop(
+    const CryptoHandshakeMessage* in) {
   QuicCryptoClientConfig::CachedState* cached =
       crypto_config_->LookupOrCreate(server_id_);
 
@@ -244,8 +305,8 @@
         break;
       case STATE_IDLE:
         // This means that the peer sent us a message that we weren't expecting.
-        CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
-                                   "Handshake in idle state");
+        stream_->CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+                                            "Handshake in idle state");
         return;
       case STATE_INITIALIZE_SCUP:
         DoInitializeServerConfigUpdate(cached);
@@ -257,7 +318,7 @@
   } while (rv != QUIC_PENDING && next_state_ != STATE_NONE);
 }
 
-void QuicCryptoClientStream::DoInitialize(
+void QuicCryptoClientHandshaker::DoInitialize(
     QuicCryptoClientConfig::CachedState* cached) {
   if (!cached->IsEmpty() && !cached->signature().empty()) {
     // Note that we verify the proof even if the cached proof is valid.
@@ -275,7 +336,7 @@
   }
 }
 
-void QuicCryptoClientStream::DoSendCHLO(
+void QuicCryptoClientHandshaker::DoSendCHLO(
     QuicCryptoClientConfig::CachedState* cached) {
   if (stateless_reject_received_) {
     // If we've gotten to this point, we've sent at least one hello
@@ -294,10 +355,11 @@
   // Send the client hello in plaintext.
   session()->connection()->SetDefaultEncryptionLevel(ENCRYPTION_NONE);
   encryption_established_ = false;
-  if (num_client_hellos_ > kMaxClientHellos) {
-    CloseConnectionWithDetails(
+  if (num_client_hellos_ > QuicCryptoClientStream::kMaxClientHellos) {
+    stream_->CloseConnectionWithDetails(
         QUIC_CRYPTO_TOO_MANY_REJECTS,
-        QuicStrCat("More than ", kMaxClientHellos, " rejects"));
+        QuicStrCat("More than ", QuicCryptoClientStream::kMaxClientHellos,
+                   " rejects"));
     return;
   }
   num_client_hellos_++;
@@ -325,13 +387,14 @@
     if (max_packet_size <= kFramingOverhead) {
       QUIC_DLOG(DFATAL) << "max_packet_length (" << max_packet_size
                         << ") has no room for framing overhead.";
-      CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
-                                 "max_packet_size too smalll");
+      stream_->CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
+                                          "max_packet_size too smalll");
       return;
     }
     if (kClientHelloMinimumSize > max_packet_size - kFramingOverhead) {
       QUIC_DLOG(DFATAL) << "Client hello won't fit in a single packet.";
-      CloseConnectionWithDetails(QUIC_INTERNAL_ERROR, "CHLO too large");
+      stream_->CloseConnectionWithDetails(QUIC_INTERNAL_ERROR,
+                                          "CHLO too large");
       return;
     }
     // TODO(rch): Remove this when we remove:
@@ -340,7 +403,7 @@
         static_cast<size_t>(max_packet_size - kFramingOverhead));
     next_state_ = STATE_RECV_REJ;
     CryptoUtils::HashHandshakeMessage(out, &chlo_hash_, Perspective::IS_CLIENT);
-    SendHandshakeMessage(out);
+    stream_->SendHandshakeMessage(out);
     return;
   }
 
@@ -364,7 +427,7 @@
     // Flush the cached config so that, if it's bad, the server has a
     // chance to send us another in the future.
     cached->InvalidateServerConfig();
-    CloseConnectionWithDetails(error, error_details);
+    stream_->CloseConnectionWithDetails(error, error_details);
     return;
   }
   CryptoUtils::HashHandshakeMessage(out, &chlo_hash_, Perspective::IS_CLIENT);
@@ -374,7 +437,7 @@
         *cached->proof_verify_details());
   }
   next_state_ = STATE_RECV_SHLO;
-  SendHandshakeMessage(out);
+  stream_->SendHandshakeMessage(out);
   // Be prepared to decrypt with the new server write key.
   session()->connection()->SetAlternativeDecrypter(
       ENCRYPTION_INITIAL,
@@ -393,7 +456,7 @@
   session()->OnCryptoHandshakeEvent(QuicSession::ENCRYPTION_REESTABLISHED);
 }
 
-void QuicCryptoClientStream::DoReceiveREJ(
+void QuicCryptoClientHandshaker::DoReceiveREJ(
     const CryptoHandshakeMessage* in,
     QuicCryptoClientConfig::CachedState* cached) {
   // We sent a dummy CHLO because we didn't have enough information to
@@ -402,8 +465,8 @@
   // that we need.
   if ((in->tag() != kREJ) && (in->tag() != kSREJ)) {
     next_state_ = STATE_NONE;
-    CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
-                               "Expected REJ");
+    stream_->CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+                                        "Expected REJ");
     return;
   }
 
@@ -421,7 +484,7 @@
       packed_error |= 1 << (reason - 1);
     }
     DVLOG(1) << "Reasons for rejection: " << packed_error;
-    if (num_client_hellos_ == kMaxClientHellos) {
+    if (num_client_hellos_ == QuicCryptoClientStream::kMaxClientHellos) {
       UMA_HISTOGRAM_SPARSE_SLOWLY("Net.QuicClientHelloRejectReasons.TooMany",
                                   packed_error);
     }
@@ -442,7 +505,7 @@
 
   if (error != QUIC_NO_ERROR) {
     next_state_ = STATE_NONE;
-    CloseConnectionWithDetails(error, error_details);
+    stream_->CloseConnectionWithDetails(error, error_details);
     return;
   }
   if (!cached->proof_valid()) {
@@ -459,7 +522,7 @@
   next_state_ = STATE_GET_CHANNEL_ID;
 }
 
-QuicAsyncStatus QuicCryptoClientStream::DoVerifyProof(
+QuicAsyncStatus QuicCryptoClientHandshaker::DoVerifyProof(
     QuicCryptoClientConfig::CachedState* cached) {
   ProofVerifier* verifier = crypto_config_->proof_verifier();
   DCHECK(verifier);
@@ -492,7 +555,7 @@
   return status;
 }
 
-void QuicCryptoClientStream::DoVerifyProofComplete(
+void QuicCryptoClientHandshaker::DoVerifyProofComplete(
     QuicCryptoClientConfig::CachedState* cached) {
   if (!proof_verify_start_time_.is_null()) {
     UMA_HISTOGRAM_TIMES("Net.QuicSession.VerifyProofTime.CachedServerConfig",
@@ -510,8 +573,8 @@
     next_state_ = STATE_NONE;
     UMA_HISTOGRAM_BOOLEAN("Net.QuicVerifyProofFailed.HandshakeConfirmed",
                           handshake_confirmed());
-    CloseConnectionWithDetails(QUIC_PROOF_INVALID,
-                               "Proof invalid: " + verify_error_details_);
+    stream_->CloseConnectionWithDetails(
+        QUIC_PROOF_INVALID, "Proof invalid: " + verify_error_details_);
     return;
   }
 
@@ -531,7 +594,7 @@
   }
 }
 
-QuicAsyncStatus QuicCryptoClientStream::DoGetChannelID(
+QuicAsyncStatus QuicCryptoClientHandshaker::DoGetChannelID(
     QuicCryptoClientConfig::CachedState* cached) {
   next_state_ = STATE_GET_CHANNEL_ID_COMPLETE;
   channel_id_key_.reset();
@@ -553,8 +616,8 @@
     case QUIC_FAILURE:
       next_state_ = STATE_NONE;
       delete channel_id_source_callback;
-      CloseConnectionWithDetails(QUIC_INVALID_CHANNEL_ID_SIGNATURE,
-                                 "Channel ID lookup failed");
+      stream_->CloseConnectionWithDetails(QUIC_INVALID_CHANNEL_ID_SIGNATURE,
+                                          "Channel ID lookup failed");
       break;
     case QUIC_SUCCESS:
       delete channel_id_source_callback;
@@ -563,17 +626,17 @@
   return status;
 }
 
-void QuicCryptoClientStream::DoGetChannelIDComplete() {
+void QuicCryptoClientHandshaker::DoGetChannelIDComplete() {
   if (!channel_id_key_.get()) {
     next_state_ = STATE_NONE;
-    CloseConnectionWithDetails(QUIC_INVALID_CHANNEL_ID_SIGNATURE,
-                               "Channel ID lookup failed");
+    stream_->CloseConnectionWithDetails(QUIC_INVALID_CHANNEL_ID_SIGNATURE,
+                                        "Channel ID lookup failed");
     return;
   }
   next_state_ = STATE_SEND_CHLO;
 }
 
-void QuicCryptoClientStream::DoReceiveSHLO(
+void QuicCryptoClientHandshaker::DoReceiveSHLO(
     const CryptoHandshakeMessage* in,
     QuicCryptoClientConfig::CachedState* cached) {
   next_state_ = STATE_NONE;
@@ -587,8 +650,8 @@
     // if we received a message encrypted with the INITIAL key.
     if (session()->connection()->alternative_decrypter() == nullptr) {
       // The rejection was sent encrypted!
-      CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
-                                 "encrypted REJ message");
+      stream_->CloseConnectionWithDetails(
+          QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT, "encrypted REJ message");
       return;
     }
     next_state_ = STATE_RECV_REJ;
@@ -596,8 +659,8 @@
   }
 
   if (in->tag() != kSHLO) {
-    CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
-                               "Expected SHLO or REJ");
+    stream_->CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+                                        "Expected SHLO or REJ");
     return;
   }
 
@@ -606,8 +669,8 @@
   // if we received a message encrypted with the INITIAL key.
   if (session()->connection()->alternative_decrypter() != nullptr) {
     // The server hello was sent without encryption.
-    CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
-                               "unencrypted SHLO message");
+    stream_->CloseConnectionWithDetails(QUIC_CRYPTO_ENCRYPTION_LEVEL_INCORRECT,
+                                        "unencrypted SHLO message");
     return;
   }
 
@@ -619,12 +682,14 @@
       crypto_negotiated_params_, &error_details);
 
   if (error != QUIC_NO_ERROR) {
-    CloseConnectionWithDetails(error, "Server hello invalid: " + error_details);
+    stream_->CloseConnectionWithDetails(
+        error, "Server hello invalid: " + error_details);
     return;
   }
   error = session()->config()->ProcessPeerHello(*in, SERVER, &error_details);
   if (error != QUIC_NO_ERROR) {
-    CloseConnectionWithDetails(error, "Server hello invalid: " + error_details);
+    stream_->CloseConnectionWithDetails(
+        error, "Server hello invalid: " + error_details);
     return;
   }
   session()->OnConfigNegotiated();
@@ -646,7 +711,7 @@
   session()->connection()->OnHandshakeComplete();
 }
 
-void QuicCryptoClientStream::DoInitializeServerConfigUpdate(
+void QuicCryptoClientHandshaker::DoInitializeServerConfigUpdate(
     QuicCryptoClientConfig::CachedState* cached) {
   bool update_ignored = false;
   if (!cached->IsEmpty() && !cached->signature().empty()) {
@@ -661,13 +726,13 @@
                           update_ignored);
 }
 
-void QuicCryptoClientStream::SetCachedProofValid(
+void QuicCryptoClientHandshaker::SetCachedProofValid(
     QuicCryptoClientConfig::CachedState* cached) {
   cached->SetProofValid();
   proof_handler_->OnProofValid(*cached);
 }
 
-bool QuicCryptoClientStream::RequiresChannelID(
+bool QuicCryptoClientHandshaker::RequiresChannelID(
     QuicCryptoClientConfig::CachedState* cached) {
   if (server_id_.privacy_mode() == PRIVACY_MODE_ENABLED ||
       !crypto_config_->channel_id_source()) {
diff --git a/net/quic/core/quic_crypto_client_stream.h b/net/quic/core/quic_crypto_client_stream.h
index d56dbd4..7707c96 100644
--- a/net/quic/core/quic_crypto_client_stream.h
+++ b/net/quic/core/quic_crypto_client_stream.h
@@ -56,6 +56,58 @@
   //     token.
   static const int kMaxClientHellos = 3;
 
+  // QuicCryptoClientStream creates a HandshakerDelegate at construction time
+  // based on the QuicVersion of the connection. Different HandshakerDelegates
+  // provide implementations of different crypto handshake protocols. Currently
+  // QUIC crypto is the only protocol implemented; a future HandshakerDelegate
+  // will use TLS as the handshake protocol. QuicCryptoClientStream delegates
+  // all of its public methods to its HandshakerDelegate.
+  //
+  // This setup of the crypto stream delegating its implementation to the
+  // handshaker results in the handshaker reading and writing bytes on the
+  // crypto stream, instead of the handshaker passing the stream bytes to send.
+  class QUIC_EXPORT_PRIVATE HandshakerDelegate {
+   public:
+    virtual ~HandshakerDelegate() {}
+
+    // Performs a crypto handshake with the server. Returns true if the
+    // connection is still connected.
+    virtual bool CryptoConnect() = 0;
+
+    // num_sent_client_hellos returns the number of client hello messages that
+    // have been sent. If the handshake has completed then this is one greater
+    // than the number of round-trips needed for the handshake.
+    virtual int num_sent_client_hellos() const = 0;
+
+    // The number of server config update messages received by the
+    // client.  Does not count update messages that were received prior
+    // to handshake confirmation.
+    virtual int num_scup_messages_received() const = 0;
+
+    // TODO(nharper): Move this to QuicCryptoClientHandshaker.
+    virtual void OnHandshakeMessage(const CryptoHandshakeMessage& message) = 0;
+
+    // Returns true if a channel ID was sent on this connection.
+    virtual bool WasChannelIDSent() const = 0;
+
+    // Returns true if our ChannelIDSourceCallback was run, which implies the
+    // ChannelIDSource operated asynchronously. Intended for testing.
+    virtual bool WasChannelIDSourceCallbackRun() const = 0;
+
+    virtual std::string chlo_hash() const = 0;
+
+    // Returns true once any encrypter (initial/0RTT or final/1RTT) has been set
+    // for the connection.
+    virtual bool encryption_established() const = 0;
+
+    // Returns true once the crypto handshake has completed.
+    virtual bool handshake_confirmed() const = 0;
+
+    // Returns the parameters negotiated in the crypto handshake.
+    virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+        const = 0;
+  };
+
   // ProofHandler is an interface that handles callbacks from the crypto
   // stream when the client has proof verification details of the server.
   class QUIC_EXPORT_PRIVATE ProofHandler {
@@ -89,6 +141,12 @@
 
   int num_scup_messages_received() const override;
 
+  // From QuicCryptoStream
+  bool encryption_established() const override;
+  bool handshake_confirmed() const override;
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override;
+
   // CryptoFramerVisitorInterface implementation
   void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
 
@@ -99,8 +157,37 @@
   // ChannelIDSource operated asynchronously. Intended for testing.
   bool WasChannelIDSourceCallbackRun() const;
 
-  std::string chlo_hash() const { return chlo_hash_; }
+  std::string chlo_hash() const;
 
+ private:
+  std::unique_ptr<HandshakerDelegate> handshaker_;
+
+  DISALLOW_COPY_AND_ASSIGN(QuicCryptoClientStream);
+};
+
+// An implementation of QuicCryptoClientStream::HandshakerDelegate which uses
+// QUIC crypto as the crypto handshake protocol.
+class QUIC_EXPORT_PRIVATE QuicCryptoClientHandshaker
+    : public QuicCryptoClientStream::HandshakerDelegate {
+ public:
+  QuicCryptoClientHandshaker(
+      const QuicServerId& server_id,
+      QuicCryptoClientStream* stream,
+      QuicSession* session,
+      ProofVerifyContext* verify_context,
+      QuicCryptoClientConfig* crypto_config,
+      QuicCryptoClientStream::ProofHandler* proof_handler);
+
+  ~QuicCryptoClientHandshaker() override;
+
+  // From QuicCryptoClientStream::HandshakerDelegate
+  bool CryptoConnect() override;
+  int num_sent_client_hellos() const override;
+  int num_scup_messages_received() const override;
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
+  bool WasChannelIDSent() const override;
+  bool WasChannelIDSourceCallbackRun() const override;
+  std::string chlo_hash() const override;
   bool encryption_established() const override;
   bool handshake_confirmed() const override;
   const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
@@ -112,7 +199,7 @@
   // channel ID lookup when lookup is performed asynchronously.
   class ChannelIDSourceCallbackImpl : public ChannelIDSourceCallback {
    public:
-    explicit ChannelIDSourceCallbackImpl(QuicCryptoClientStream* stream);
+    explicit ChannelIDSourceCallbackImpl(QuicCryptoClientHandshaker* parent);
     ~ChannelIDSourceCallbackImpl() override;
 
     // ChannelIDSourceCallback interface.
@@ -123,7 +210,7 @@
     void Cancel();
 
    private:
-    QuicCryptoClientStream* stream_;
+    QuicCryptoClientHandshaker* parent_;
   };
 
   // ProofVerifierCallbackImpl is passed as the callback method to VerifyProof.
@@ -131,7 +218,7 @@
   // when verification is performed asynchronously.
   class ProofVerifierCallbackImpl : public ProofVerifierCallback {
    public:
-    explicit ProofVerifierCallbackImpl(QuicCryptoClientStream* stream);
+    explicit ProofVerifierCallbackImpl(QuicCryptoClientHandshaker* parent);
     ~ProofVerifierCallbackImpl() override;
 
     // ProofVerifierCallback interface.
@@ -144,7 +231,7 @@
     void Cancel();
 
    private:
-    QuicCryptoClientStream* stream_;
+    QuicCryptoClientHandshaker* parent_;
   };
 
   friend class test::QuicChromiumClientSessionPeer;
@@ -216,6 +303,13 @@
   // and the client config settings also allow sending a ChannelID.
   bool RequiresChannelID(QuicCryptoClientConfig::CachedState* cached);
 
+  // Returns the QuicSession that this stream belongs to.
+  QuicSession* session() const { return session_; }
+
+  QuicCryptoClientStream* stream_;
+
+  QuicSession* session_;
+
   State next_state_;
   // num_client_hellos_ contains the number of client hello messages that this
   // connection has sent.
@@ -257,7 +351,7 @@
   ProofVerifierCallbackImpl* proof_verify_callback_;
   // proof_handler_ contains the callback object used by a quic client
   // for proof verification. It is not owned by this class.
-  ProofHandler* proof_handler_;
+  QuicCryptoClientStream::ProofHandler* proof_handler_;
 
   // These members are used to store the result of an asynchronous proof
   // verification. These members must not be used after
@@ -281,7 +375,7 @@
   QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters>
       crypto_negotiated_params_;
 
-  DISALLOW_COPY_AND_ASSIGN(QuicCryptoClientStream);
+  DISALLOW_COPY_AND_ASSIGN(QuicCryptoClientHandshaker);
 };
 
 }  // namespace net
diff --git a/net/quic/core/quic_crypto_client_stream_test.cc b/net/quic/core/quic_crypto_client_stream_test.cc
index e841dff2..92ca0dd 100644
--- a/net/quic/core/quic_crypto_client_stream_test.cc
+++ b/net/quic/core/quic_crypto_client_stream_test.cc
@@ -314,6 +314,14 @@
                                           /*offset=*/0, data->AsStringPiece()));
 }
 
+TEST_F(QuicCryptoClientStreamTest, NoChannelID) {
+  crypto_config_.SetChannelIDSource(nullptr);
+
+  CompleteCryptoHandshake();
+  EXPECT_FALSE(stream()->WasChannelIDSent());
+  EXPECT_FALSE(stream()->WasChannelIDSourceCallbackRun());
+}
+
 TEST_F(QuicCryptoClientStreamTest, TokenBindingNegotiation) {
   server_options_.token_binding_params = QuicTagVector{kTB10, kP256};
   crypto_config_.tb_key_params = QuicTagVector{kTB10};
diff --git a/net/quic/core/quic_crypto_server_stream.cc b/net/quic/core/quic_crypto_server_stream.cc
index 4dd9da7..98c63d5 100644
--- a/net/quic/core/quic_crypto_server_stream.cc
+++ b/net/quic/core/quic_crypto_server_stream.cc
@@ -24,14 +24,14 @@
 
 namespace net {
 
-class QuicCryptoServerStream::ProcessClientHelloCallback
+class QuicCryptoServerHandshaker::ProcessClientHelloCallback
     : public ProcessClientHelloResultCallback {
  public:
   ProcessClientHelloCallback(
-      QuicCryptoServerStream* stream,
+      QuicCryptoServerHandshaker* parent,
       const QuicReferenceCountedPointer<
           ValidateClientHelloResultCallback::Result>& result)
-      : stream_(stream), result_(result) {}
+      : parent_(parent), result_(result) {}
 
   void Run(QuicErrorCode error,
            const string& error_details,
@@ -39,19 +39,19 @@
            std::unique_ptr<DiversificationNonce> diversification_nonce,
            std::unique_ptr<net::ProofSource::Details> proof_source_details)
       override {
-    if (stream_ == nullptr) {
+    if (parent_ == nullptr) {
       return;
     }
 
-    stream_->FinishProcessingHandshakeMessageAfterProcessClientHello(
+    parent_->FinishProcessingHandshakeMessageAfterProcessClientHello(
         *result_, error, error_details, std::move(message),
         std::move(diversification_nonce), std::move(proof_source_details));
   }
 
-  void Cancel() { stream_ = nullptr; }
+  void Cancel() { parent_ = nullptr; }
 
  private:
-  QuicCryptoServerStream* stream_;
+  QuicCryptoServerHandshaker* parent_;
   QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
       result_;
 };
@@ -83,7 +83,106 @@
     bool use_stateless_rejects_if_peer_supported,
     QuicSession* session,
     Helper* helper)
-    : QuicCryptoServerStreamBase(session),
+    : QuicCryptoServerStreamBase(session) {
+  DCHECK_EQ(Perspective::IS_SERVER, session->connection()->perspective());
+  handshaker_.reset(new QuicCryptoServerHandshaker(
+      crypto_config, this, compressed_certs_cache,
+      use_stateless_rejects_if_peer_supported, session, helper));
+}
+
+QuicCryptoServerStream::~QuicCryptoServerStream() {}
+
+void QuicCryptoServerStream::CancelOutstandingCallbacks() {
+  handshaker()->CancelOutstandingCallbacks();
+}
+
+void QuicCryptoServerStream::OnHandshakeMessage(
+    const CryptoHandshakeMessage& message) {
+  QuicCryptoServerStreamBase::OnHandshakeMessage(message);
+  handshaker()->OnHandshakeMessage(message);
+}
+
+bool QuicCryptoServerStream::GetBase64SHA256ClientChannelID(
+    string* output) const {
+  return handshaker()->GetBase64SHA256ClientChannelID(output);
+}
+
+void QuicCryptoServerStream::SendServerConfigUpdate(
+    const CachedNetworkParameters* cached_network_params) {
+  handshaker()->SendServerConfigUpdate(cached_network_params);
+}
+
+uint8_t QuicCryptoServerStream::NumHandshakeMessages() const {
+  return handshaker()->NumHandshakeMessages();
+}
+
+uint8_t QuicCryptoServerStream::NumHandshakeMessagesWithServerNonces() const {
+  return handshaker()->NumHandshakeMessagesWithServerNonces();
+}
+
+int QuicCryptoServerStream::NumServerConfigUpdateMessagesSent() const {
+  return handshaker()->NumServerConfigUpdateMessagesSent();
+}
+
+const CachedNetworkParameters*
+QuicCryptoServerStream::PreviousCachedNetworkParams() const {
+  return handshaker()->PreviousCachedNetworkParams();
+}
+
+bool QuicCryptoServerStream::UseStatelessRejectsIfPeerSupported() const {
+  return handshaker()->UseStatelessRejectsIfPeerSupported();
+}
+
+bool QuicCryptoServerStream::PeerSupportsStatelessRejects() const {
+  return handshaker()->PeerSupportsStatelessRejects();
+}
+
+bool QuicCryptoServerStream::ZeroRttAttempted() const {
+  return handshaker()->ZeroRttAttempted();
+}
+
+void QuicCryptoServerStream::SetPeerSupportsStatelessRejects(
+    bool peer_supports_stateless_rejects) {
+  handshaker()->SetPeerSupportsStatelessRejects(
+      peer_supports_stateless_rejects);
+}
+
+void QuicCryptoServerStream::SetPreviousCachedNetworkParams(
+    CachedNetworkParameters cached_network_params) {
+  handshaker()->SetPreviousCachedNetworkParams(cached_network_params);
+}
+
+bool QuicCryptoServerStream::ShouldSendExpectCTHeader() const {
+  return handshaker()->ShouldSendExpectCTHeader();
+}
+
+bool QuicCryptoServerStream::encryption_established() const {
+  return handshaker()->encryption_established();
+}
+
+bool QuicCryptoServerStream::handshake_confirmed() const {
+  return handshaker()->handshake_confirmed();
+}
+
+const QuicCryptoNegotiatedParameters&
+QuicCryptoServerStream::crypto_negotiated_params() const {
+  return handshaker()->crypto_negotiated_params();
+}
+
+QuicCryptoServerStream::HandshakerDelegate* QuicCryptoServerStream::handshaker()
+    const {
+  return handshaker_.get();
+}
+
+QuicCryptoServerHandshaker::QuicCryptoServerHandshaker(
+    const QuicCryptoServerConfig* crypto_config,
+    QuicCryptoServerStream* stream,
+    QuicCompressedCertsCache* compressed_certs_cache,
+    bool use_stateless_rejects_if_peer_supported,
+    QuicSession* session,
+    QuicCryptoServerStream::Helper* helper)
+    : stream_(stream),
+      session_(session),
       crypto_config_(crypto_config),
       compressed_certs_cache_(compressed_certs_cache),
       signed_config_(new QuicSignedServerConfig),
@@ -101,15 +200,13 @@
       process_client_hello_cb_(nullptr),
       encryption_established_(false),
       handshake_confirmed_(false),
-      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {
-  DCHECK_EQ(Perspective::IS_SERVER, session->connection()->perspective());
-}
+      crypto_negotiated_params_(new QuicCryptoNegotiatedParameters) {}
 
-QuicCryptoServerStream::~QuicCryptoServerStream() {
+QuicCryptoServerHandshaker::~QuicCryptoServerHandshaker() {
   CancelOutstandingCallbacks();
 }
 
-void QuicCryptoServerStream::CancelOutstandingCallbacks() {
+void QuicCryptoServerHandshaker::CancelOutstandingCallbacks() {
   // Detach from the validation callback.  Calling this multiple times is safe.
   if (validate_client_hello_cb_ != nullptr) {
     validate_client_hello_cb_->Cancel();
@@ -125,22 +222,22 @@
   }
 }
 
-void QuicCryptoServerStream::OnHandshakeMessage(
+void QuicCryptoServerHandshaker::OnHandshakeMessage(
     const CryptoHandshakeMessage& message) {
-  QuicCryptoServerStreamBase::OnHandshakeMessage(message);
   ++num_handshake_messages_;
   chlo_packet_size_ = session()->connection()->GetCurrentPacket().length();
 
   // Do not process handshake messages after the handshake is confirmed.
   if (handshake_confirmed_) {
-    CloseConnectionWithDetails(QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
-                               "Unexpected handshake message from client");
+    stream_->CloseConnectionWithDetails(
+        QUIC_CRYPTO_MESSAGE_AFTER_HANDSHAKE_COMPLETE,
+        "Unexpected handshake message from client");
     return;
   }
 
   if (message.tag() != kCHLO) {
-    CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
-                               "Handshake packet not CHLO");
+    stream_->CloseConnectionWithDetails(QUIC_INVALID_CRYPTO_MESSAGE_TYPE,
+                                        "Handshake packet not CHLO");
     return;
   }
 
@@ -149,7 +246,7 @@
     // Already processing some other handshake message.  The protocol
     // does not allow for clients to send multiple handshake messages
     // before the server has a chance to respond.
-    CloseConnectionWithDetails(
+    stream_->CloseConnectionWithDetails(
         QUIC_CRYPTO_MESSAGE_WHILE_VALIDATING_CLIENT_HELLO,
         "Unexpected handshake message while processing CHLO");
     return;
@@ -168,7 +265,7 @@
       session()->connection()->clock(), signed_config_, std::move(cb));
 }
 
-void QuicCryptoServerStream::FinishProcessingHandshakeMessage(
+void QuicCryptoServerHandshaker::FinishProcessingHandshakeMessage(
     QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
         result,
     std::unique_ptr<ProofSource::Details> details) {
@@ -180,7 +277,8 @@
   validate_client_hello_cb_ = nullptr;
 
   if (use_stateless_rejects_if_peer_supported_) {
-    peer_supports_stateless_rejects_ = DoesPeerSupportStatelessRejects(message);
+    peer_supports_stateless_rejects_ =
+        QuicCryptoServerStreamBase::DoesPeerSupportStatelessRejects(message);
   }
 
   std::unique_ptr<ProcessClientHelloCallback> cb(
@@ -189,7 +287,7 @@
   ProcessClientHello(result, std::move(details), std::move(cb));
 }
 
-void QuicCryptoServerStream::
+void QuicCryptoServerHandshaker::
     FinishProcessingHandshakeMessageAfterProcessClientHello(
         const ValidateClientHelloResultCallback::Result& result,
         QuicErrorCode error,
@@ -204,7 +302,7 @@
 
   const CryptoHandshakeMessage& message = result.client_hello;
   if (error != QUIC_NO_ERROR) {
-    CloseConnectionWithDetails(error, error_details);
+    stream_->CloseConnectionWithDetails(error, error_details);
     return;
   }
 
@@ -217,7 +315,7 @@
       // retransmitted.
       session()->connection()->EnableSavingCryptoPackets();
     }
-    SendHandshakeMessage(*reply);
+    stream_->SendHandshakeMessage(*reply);
 
     if (reply->tag() == kSREJ) {
       DCHECK(use_stateless_rejects_if_peer_supported_);
@@ -242,7 +340,7 @@
   const QuicErrorCode process_error =
       config->ProcessPeerHello(message, CLIENT, &process_error_details);
   if (process_error != QUIC_NO_ERROR) {
-    CloseConnectionWithDetails(process_error, process_error_details);
+    stream_->CloseConnectionWithDetails(process_error, process_error_details);
     return;
   }
 
@@ -266,7 +364,7 @@
       crypto_negotiated_params_->initial_crypters.decrypter.release());
   session()->connection()->SetDiversificationNonce(*diversification_nonce);
 
-  SendHandshakeMessage(*reply);
+  stream_->SendHandshakeMessage(*reply);
 
   session()->connection()->SetEncrypter(
       ENCRYPTION_FORWARD_SECURE,
@@ -283,7 +381,7 @@
   session()->OnCryptoHandshakeEvent(QuicSession::HANDSHAKE_CONFIRMED);
 }
 
-void QuicCryptoServerStream::SendServerConfigUpdate(
+void QuicCryptoServerHandshaker::SendServerConfigUpdate(
     const CachedNetworkParameters* cached_network_params) {
   if (!handshake_confirmed_) {
     return;
@@ -311,16 +409,16 @@
       std::move(cb));
 }
 
-QuicCryptoServerStream::SendServerConfigUpdateCallback::
-    SendServerConfigUpdateCallback(QuicCryptoServerStream* parent)
+QuicCryptoServerHandshaker::SendServerConfigUpdateCallback::
+    SendServerConfigUpdateCallback(QuicCryptoServerHandshaker* parent)
     : parent_(parent) {}
 
-void QuicCryptoServerStream::SendServerConfigUpdateCallback::Cancel() {
+void QuicCryptoServerHandshaker::SendServerConfigUpdateCallback::Cancel() {
   parent_ = nullptr;
 }
 
 // From BuildServerConfigUpdateMessageResultCallback
-void QuicCryptoServerStream::SendServerConfigUpdateCallback::Run(
+void QuicCryptoServerHandshaker::SendServerConfigUpdateCallback::Run(
     bool ok,
     const CryptoHandshakeMessage& message) {
   if (parent_ == nullptr) {
@@ -329,7 +427,7 @@
   parent_->FinishSendServerConfigUpdate(ok, message);
 }
 
-void QuicCryptoServerStream::FinishSendServerConfigUpdate(
+void QuicCryptoServerHandshaker::FinishSendServerConfigUpdate(
     bool ok,
     const CryptoHandshakeMessage& message) {
   // Clear the callback that got us here.
@@ -344,53 +442,58 @@
   QUIC_DVLOG(1) << "Server: Sending server config update: "
                 << message.DebugString(Perspective::IS_SERVER);
   const QuicData& data = message.GetSerialized(Perspective::IS_SERVER);
-  WriteOrBufferData(QuicStringPiece(data.data(), data.length()), false,
-                    nullptr);
+  stream_->WriteOrBufferData(QuicStringPiece(data.data(), data.length()), false,
+                             nullptr);
 
   ++num_server_config_update_messages_sent_;
 }
 
-uint8_t QuicCryptoServerStream::NumHandshakeMessages() const {
+uint8_t QuicCryptoServerHandshaker::NumHandshakeMessages() const {
   return num_handshake_messages_;
 }
 
-uint8_t QuicCryptoServerStream::NumHandshakeMessagesWithServerNonces() const {
+uint8_t QuicCryptoServerHandshaker::NumHandshakeMessagesWithServerNonces()
+    const {
   return num_handshake_messages_with_server_nonces_;
 }
 
-int QuicCryptoServerStream::NumServerConfigUpdateMessagesSent() const {
+int QuicCryptoServerHandshaker::NumServerConfigUpdateMessagesSent() const {
   return num_server_config_update_messages_sent_;
 }
 
 const CachedNetworkParameters*
-QuicCryptoServerStream::PreviousCachedNetworkParams() const {
+QuicCryptoServerHandshaker::PreviousCachedNetworkParams() const {
   return previous_cached_network_params_.get();
 }
 
-bool QuicCryptoServerStream::UseStatelessRejectsIfPeerSupported() const {
+bool QuicCryptoServerHandshaker::UseStatelessRejectsIfPeerSupported() const {
   return use_stateless_rejects_if_peer_supported_;
 }
 
-bool QuicCryptoServerStream::PeerSupportsStatelessRejects() const {
+bool QuicCryptoServerHandshaker::PeerSupportsStatelessRejects() const {
   return peer_supports_stateless_rejects_;
 }
 
-bool QuicCryptoServerStream::ZeroRttAttempted() const {
+bool QuicCryptoServerHandshaker::ZeroRttAttempted() const {
   return zero_rtt_attempted_;
 }
 
-void QuicCryptoServerStream::SetPeerSupportsStatelessRejects(
+void QuicCryptoServerHandshaker::SetPeerSupportsStatelessRejects(
     bool peer_supports_stateless_rejects) {
   peer_supports_stateless_rejects_ = peer_supports_stateless_rejects;
 }
 
-void QuicCryptoServerStream::SetPreviousCachedNetworkParams(
+void QuicCryptoServerHandshaker::SetPreviousCachedNetworkParams(
     CachedNetworkParameters cached_network_params) {
   previous_cached_network_params_.reset(
       new CachedNetworkParameters(cached_network_params));
 }
 
-bool QuicCryptoServerStream::GetBase64SHA256ClientChannelID(
+bool QuicCryptoServerHandshaker::ShouldSendExpectCTHeader() const {
+  return signed_config_->proof.send_expect_ct_header;
+}
+
+bool QuicCryptoServerHandshaker::GetBase64SHA256ClientChannelID(
     string* output) const {
   if (!encryption_established() ||
       crypto_negotiated_params_->channel_id.empty()) {
@@ -406,20 +509,20 @@
   return true;
 }
 
-bool QuicCryptoServerStream::encryption_established() const {
+bool QuicCryptoServerHandshaker::encryption_established() const {
   return encryption_established_;
 }
 
-bool QuicCryptoServerStream::handshake_confirmed() const {
+bool QuicCryptoServerHandshaker::handshake_confirmed() const {
   return handshake_confirmed_;
 }
 
 const QuicCryptoNegotiatedParameters&
-QuicCryptoServerStream::crypto_negotiated_params() const {
+QuicCryptoServerHandshaker::crypto_negotiated_params() const {
   return *crypto_negotiated_params_;
 }
 
-void QuicCryptoServerStream::ProcessClientHello(
+void QuicCryptoServerHandshaker::ProcessClientHello(
     QuicReferenceCountedPointer<ValidateClientHelloResultCallback::Result>
         result,
     std::unique_ptr<ProofSource::Details> proof_source_details,
@@ -466,17 +569,18 @@
       chlo_packet_size_, std::move(done_cb));
 }
 
-void QuicCryptoServerStream::OverrideQuicConfigDefaults(QuicConfig* config) {}
+void QuicCryptoServerHandshaker::OverrideQuicConfigDefaults(
+    QuicConfig* config) {}
 
-QuicCryptoServerStream::ValidateCallback::ValidateCallback(
-    QuicCryptoServerStream* parent)
+QuicCryptoServerHandshaker::ValidateCallback::ValidateCallback(
+    QuicCryptoServerHandshaker* parent)
     : parent_(parent) {}
 
-void QuicCryptoServerStream::ValidateCallback::Cancel() {
+void QuicCryptoServerHandshaker::ValidateCallback::Cancel() {
   parent_ = nullptr;
 }
 
-void QuicCryptoServerStream::ValidateCallback::Run(
+void QuicCryptoServerHandshaker::ValidateCallback::Run(
     QuicReferenceCountedPointer<Result> result,
     std::unique_ptr<ProofSource::Details> details) {
   if (parent_ != nullptr) {
@@ -485,7 +589,7 @@
   }
 }
 
-QuicConnectionId QuicCryptoServerStream::GenerateConnectionIdForReject(
+QuicConnectionId QuicCryptoServerHandshaker::GenerateConnectionIdForReject(
     bool use_stateless_rejects) {
   if (!use_stateless_rejects) {
     return 0;
@@ -494,7 +598,7 @@
       session()->connection()->connection_id());
 }
 
-const QuicSocketAddress QuicCryptoServerStream::GetClientAddress() {
+const QuicSocketAddress QuicCryptoServerHandshaker::GetClientAddress() {
   return session()->connection()->peer_address();
 }
 
diff --git a/net/quic/core/quic_crypto_server_stream.h b/net/quic/core/quic_crypto_server_stream.h
index 9bbfcf2..f187991 100644
--- a/net/quic/core/quic_crypto_server_stream.h
+++ b/net/quic/core/quic_crypto_server_stream.h
@@ -16,6 +16,7 @@
 #include "net/quic/core/proto/source_address_token.pb.h"
 #include "net/quic/core/quic_config.h"
 #include "net/quic/core/quic_crypto_stream.h"
+#include "net/quic/core/quic_session.h"
 #include "net/quic/platform/api/quic_export.h"
 
 namespace net {
@@ -73,6 +74,69 @@
 class QUIC_EXPORT_PRIVATE QuicCryptoServerStream
     : public QuicCryptoServerStreamBase {
  public:
+  // QuicCryptoServerStream creates a HandshakerDelegate at construction time
+  // based on the QuicVersion of the connection. Different HandshakerDelegates
+  // provide implementations of different crypto handshake protocols. Currently
+  // QUIC crypto is the only protocol implemented; a future HandshakerDelegate
+  // will use TLS as the handshake protocol. QuicCryptoServerStream delegates
+  // all of its public methods to its HandshakerDelegate.
+  //
+  // This setup of the crypto stream delegating its implementation to the
+  // handshaker results in the handshaker reading and writing bytes on the
+  // crypto stream, instead of the handshake rpassing the stream bytes to send.
+  class QUIC_EXPORT_PRIVATE HandshakerDelegate {
+   public:
+    virtual ~HandshakerDelegate() {}
+
+    // Cancel any outstanding callbacks, such as asynchronous validation of
+    // client hello.
+    virtual void CancelOutstandingCallbacks() = 0;
+
+    // TODO(nharper): Move this to QuicCryptoServerHandshaker.
+    virtual void OnHandshakeMessage(const CryptoHandshakeMessage& message) = 0;
+
+    // GetBase64SHA256ClientChannelID sets |*output| to the base64 encoded,
+    // SHA-256 hash of the client's ChannelID key and returns true, if the
+    // client presented a ChannelID. Otherwise it returns false.
+    virtual bool GetBase64SHA256ClientChannelID(std::string* output) const = 0;
+
+    // Sends the latest server config and source-address token to the client.
+    virtual void SendServerConfigUpdate(
+        const CachedNetworkParameters* cached_network_params) = 0;
+
+    // These are all accessors and setters to their respective counters.
+    virtual uint8_t NumHandshakeMessages() const = 0;
+    virtual uint8_t NumHandshakeMessagesWithServerNonces() const = 0;
+    virtual int NumServerConfigUpdateMessagesSent() const = 0;
+    virtual const CachedNetworkParameters* PreviousCachedNetworkParams()
+        const = 0;
+    virtual bool UseStatelessRejectsIfPeerSupported() const = 0;
+    virtual bool PeerSupportsStatelessRejects() const = 0;
+    virtual bool ZeroRttAttempted() const = 0;
+    virtual void SetPeerSupportsStatelessRejects(
+        bool peer_supports_stateless_rejects) = 0;
+    virtual void SetPreviousCachedNetworkParams(
+        CachedNetworkParameters cached_network_params) = 0;
+
+    // NOTE: Indicating that the Expect-CT header should be sent here presents a
+    // layering violation to some extent. The Expect-CT header only applies to
+    // HTTP connections, while this class can be used for non-HTTP applications.
+    // However, it is exposed here because that is the only place where the
+    // configuration for the certificate used in the connection is accessible.
+    virtual bool ShouldSendExpectCTHeader() const = 0;
+
+    // Returns true once any encrypter (initial/0RTT or final/1RTT) has been set
+    // for the connection.
+    virtual bool encryption_established() const = 0;
+
+    // Returns true once the crypto handshake has completed.
+    virtual bool handshake_confirmed() const = 0;
+
+    // Returns the parameters negotiated in the crypto handshake.
+    virtual const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+        const = 0;
+  };
+
   class Helper {
    public:
     virtual ~Helper() {}
@@ -124,9 +188,56 @@
   // HTTP connections, while this class can be used for non-HTTP applications.
   // However, it is exposed here because that is the only place where the
   // configuration for the certificate used in the connection is accessible.
-  bool ShouldSendExpectCTHeader() const {
-    return signed_config_->proof.send_expect_ct_header;
-  }
+  bool ShouldSendExpectCTHeader() const;
+
+  bool encryption_established() const override;
+  bool handshake_confirmed() const override;
+  const QuicCryptoNegotiatedParameters& crypto_negotiated_params()
+      const override;
+
+ protected:
+  // Provided so that subclasses can provide their own handshaker.
+  virtual HandshakerDelegate* handshaker() const;
+
+ private:
+  std::unique_ptr<HandshakerDelegate> handshaker_;
+
+  DISALLOW_COPY_AND_ASSIGN(QuicCryptoServerStream);
+};
+
+class QUIC_EXPORT_PRIVATE QuicCryptoServerHandshaker
+    : public QuicCryptoServerStream::HandshakerDelegate {
+ public:
+  // |crypto_config| must outlive the stream.
+  // |session| must outlive the stream.
+  // |helper| must outlive the stream.
+  QuicCryptoServerHandshaker(const QuicCryptoServerConfig* crypto_config,
+                             QuicCryptoServerStream* stream,
+                             QuicCompressedCertsCache* compressed_certs_cache,
+                             bool use_stateless_rejects_if_peer_supported,
+                             QuicSession* session,
+                             QuicCryptoServerStream::Helper* helper);
+
+  ~QuicCryptoServerHandshaker() override;
+
+  // From HandshakerDelegate
+  void CancelOutstandingCallbacks() override;
+  void OnHandshakeMessage(const CryptoHandshakeMessage& message) override;
+  bool GetBase64SHA256ClientChannelID(std::string* output) const override;
+  void SendServerConfigUpdate(
+      const CachedNetworkParameters* cached_network_params) override;
+  uint8_t NumHandshakeMessages() const override;
+  uint8_t NumHandshakeMessagesWithServerNonces() const override;
+  int NumServerConfigUpdateMessagesSent() const override;
+  const CachedNetworkParameters* PreviousCachedNetworkParams() const override;
+  bool UseStatelessRejectsIfPeerSupported() const override;
+  bool PeerSupportsStatelessRejects() const override;
+  bool ZeroRttAttempted() const override;
+  void SetPeerSupportsStatelessRejects(
+      bool peer_supports_stateless_rejects) override;
+  void SetPreviousCachedNetworkParams(
+      CachedNetworkParameters cached_network_params) override;
+  bool ShouldSendExpectCTHeader() const override;
 
   bool encryption_established() const override;
   bool handshake_confirmed() const override;
@@ -152,7 +263,7 @@
 
   class ValidateCallback : public ValidateClientHelloResultCallback {
    public:
-    explicit ValidateCallback(QuicCryptoServerStream* parent);
+    explicit ValidateCallback(QuicCryptoServerHandshaker* parent);
     // To allow the parent to detach itself from the callback before deletion.
     void Cancel();
 
@@ -161,7 +272,7 @@
              std::unique_ptr<ProofSource::Details> details) override;
 
    private:
-    QuicCryptoServerStream* parent_;
+    QuicCryptoServerHandshaker* parent_;
 
     DISALLOW_COPY_AND_ASSIGN(ValidateCallback);
   };
@@ -169,7 +280,7 @@
   class SendServerConfigUpdateCallback
       : public BuildServerConfigUpdateMessageResultCallback {
    public:
-    explicit SendServerConfigUpdateCallback(QuicCryptoServerStream* parent);
+    explicit SendServerConfigUpdateCallback(QuicCryptoServerHandshaker* parent);
     SendServerConfigUpdateCallback(const SendServerConfigUpdateCallback&) =
         delete;
     void operator=(const SendServerConfigUpdateCallback&) = delete;
@@ -181,7 +292,7 @@
     void Run(bool ok, const CryptoHandshakeMessage& message) override;
 
    private:
-    QuicCryptoServerStream* parent_;
+    QuicCryptoServerHandshaker* parent_;
   };
 
   // Invoked by ValidateCallback::RunImpl once initial validation of
@@ -216,6 +327,16 @@
   // if |use_stateless_rejects| is true. Returns 0 otherwise.
   QuicConnectionId GenerateConnectionIdForReject(bool use_stateless_rejects);
 
+  // Returns the QuicSession that this stream belongs to.
+  QuicSession* session() const { return session_; }
+
+  // Returns the QuicVersion of the connection.
+  QuicVersion version() const { return session_->connection()->version(); }
+
+  QuicCryptoServerStream* stream_;
+
+  QuicSession* session_;
+
   // crypto_config_ contains crypto parameters for the handshake.
   const QuicCryptoServerConfig* crypto_config_;
 
@@ -232,7 +353,7 @@
   std::string chlo_hash_;
 
   // Pointer to the helper for this crypto stream. Must outlive this stream.
-  Helper* helper_;
+  QuicCryptoServerStream::Helper* helper_;
 
   // Number of handshake messages received by this stream.
   uint8_t num_handshake_messages_;
@@ -295,7 +416,7 @@
   QuicReferenceCountedPointer<QuicCryptoNegotiatedParameters>
       crypto_negotiated_params_;
 
-  DISALLOW_COPY_AND_ASSIGN(QuicCryptoServerStream);
+  DISALLOW_COPY_AND_ASSIGN(QuicCryptoServerHandshaker);
 };
 
 }  // namespace net
diff --git a/net/quic/core/quic_headers_stream_test.cc b/net/quic/core/quic_headers_stream_test.cc
index 0993c61a..c834b063 100644
--- a/net/quic/core/quic_headers_stream_test.cc
+++ b/net/quic/core/quic_headers_stream_test.cc
@@ -75,7 +75,7 @@
                     size_t len));
   MOCK_METHOD2(OnRstStream,
                void(SpdyStreamId stream_id, SpdyErrorCode error_code));
-  MOCK_METHOD1(OnSettings, void(bool clear_persisted));
+  MOCK_METHOD0(OnSettings, void());
   MOCK_METHOD2(OnSetting, void(SpdySettingsIds id, uint32_t value));
   MOCK_METHOD0(OnSettingsAck, void());
   MOCK_METHOD0(OnSettingsEnd, void());
diff --git a/net/spdy/chromium/buffered_spdy_framer.cc b/net/spdy/chromium/buffered_spdy_framer.cc
index 8acb698..2e52b01 100644
--- a/net/spdy/chromium/buffered_spdy_framer.cc
+++ b/net/spdy/chromium/buffered_spdy_framer.cc
@@ -127,7 +127,7 @@
   control_frame_fields_.reset(NULL);
 }
 
-void BufferedSpdyFramer::OnSettings(bool clear_persisted) {
+void BufferedSpdyFramer::OnSettings() {
   visitor_->OnSettings();
 }
 
diff --git a/net/spdy/chromium/buffered_spdy_framer.h b/net/spdy/chromium/buffered_spdy_framer.h
index 935eb37..510f4cf 100644
--- a/net/spdy/chromium/buffered_spdy_framer.h
+++ b/net/spdy/chromium/buffered_spdy_framer.h
@@ -153,7 +153,7 @@
   SpdyHeadersHandlerInterface* OnHeaderFrameStart(
       SpdyStreamId stream_id) override;
   void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override;
-  void OnSettings(bool clear_persisted) override;
+  void OnSettings() override;
   void OnSetting(SpdySettingsIds id, uint32_t value) override;
   void OnSettingsAck() override;
   void OnSettingsEnd() override;
diff --git a/net/spdy/core/http2_frame_decoder_adapter.cc b/net/spdy/core/http2_frame_decoder_adapter.cc
index 09c6c113..91d7a609 100644
--- a/net/spdy/core/http2_frame_decoder_adapter.cc
+++ b/net/spdy/core/http2_frame_decoder_adapter.cc
@@ -375,7 +375,7 @@
     if (IsOkToStartFrame(header) && HasRequiredStreamIdZero(header)) {
       frame_header_ = header;
       has_frame_header_ = true;
-      visitor()->OnSettings(0);
+      visitor()->OnSettings();
     }
   }
 
diff --git a/net/spdy/core/mock_spdy_framer_visitor.h b/net/spdy/core/mock_spdy_framer_visitor.h
index b312712..8f06f01 100644
--- a/net/spdy/core/mock_spdy_framer_visitor.h
+++ b/net/spdy/core/mock_spdy_framer_visitor.h
@@ -38,7 +38,7 @@
   MOCK_METHOD2(OnHeaderFrameEnd, void(SpdyStreamId stream_id, bool end));
   MOCK_METHOD2(OnRstStream,
                void(SpdyStreamId stream_id, SpdyErrorCode error_code));
-  MOCK_METHOD1(OnSettings, void(bool clear_persisted));
+  MOCK_METHOD0(OnSettings, void());
   MOCK_METHOD2(OnSetting, void(SpdySettingsIds id, uint32_t value));
   MOCK_METHOD2(OnPing, void(SpdyPingId unique_id, bool is_ack));
   MOCK_METHOD0(OnSettingsEnd, void());
diff --git a/net/spdy/core/spdy_deframer_visitor.cc b/net/spdy/core/spdy_deframer_visitor.cc
index 51d165d..248f8ef 100644
--- a/net/spdy/core/spdy_deframer_visitor.cc
+++ b/net/spdy/core/spdy_deframer_visitor.cc
@@ -166,7 +166,7 @@
                      bool end) override;
   void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override;
   void OnSetting(SpdySettingsIds id, uint32_t value) override;
-  void OnSettings(bool clear_persisted) override;
+  void OnSettings() override;
   void OnSettingsAck() override;
   void OnSettingsEnd() override;
   void OnStreamFrameData(SpdyStreamId stream_id,
@@ -618,8 +618,7 @@
 // Called at the start of a SETTINGS frame with setting entries, but not the
 // (required) ACK of a SETTINGS frame. There is no stream_id because
 // the settings apply to the entire connection, not to an individual stream.
-// The |clear_persisted| flag is a pre-HTTP/2 remnant.
-void SpdyTestDeframerImpl::OnSettings(bool /*clear_persisted*/) {
+void SpdyTestDeframerImpl::OnSettings() {
   DVLOG(1) << "OnSettings";
   CHECK_EQ(frame_type_, UNSET) << "   frame_type_="
                                << Http2FrameTypeToString(frame_type_);
diff --git a/net/spdy/core/spdy_framer.cc b/net/spdy/core/spdy_framer.cc
index 68aee37..b1d8d8c 100644
--- a/net/spdy/core/spdy_framer.cc
+++ b/net/spdy/core/spdy_framer.cc
@@ -1164,8 +1164,7 @@
       visitor_->OnSettingsAck();
       CHANGE_STATE(SPDY_FRAME_COMPLETE);
     } else {
-      visitor_->OnSettings(current_frame_flags_ &
-                           SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS);
+      visitor_->OnSettings();
       CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD);
     }
   }
diff --git a/net/spdy/core/spdy_framer.h b/net/spdy/core/spdy_framer.h
index ae827fa..d7f07e0 100644
--- a/net/spdy/core/spdy_framer.h
+++ b/net/spdy/core/spdy_framer.h
@@ -122,8 +122,7 @@
                            SpdyErrorCode error_code) = 0;
 
   // Called when a SETTINGS frame is received.
-  // |clear_persisted| True if the respective flag is set on the SETTINGS frame.
-  virtual void OnSettings(bool clear_persisted) {}
+  virtual void OnSettings() {}
 
   // Called when a complete setting within a SETTINGS frame has been parsed and
   // validated.
diff --git a/net/spdy/core/spdy_framer_decoder_adapter.cc b/net/spdy/core/spdy_framer_decoder_adapter.cc
index 2b95b1a..1f2ebff 100644
--- a/net/spdy/core/spdy_framer_decoder_adapter.cc
+++ b/net/spdy/core/spdy_framer_decoder_adapter.cc
@@ -100,8 +100,8 @@
   visitor_->OnPing(unique_id, is_ack);
 }
 
-void SpdyFramerVisitorAdapter::OnSettings(bool clear_persisted) {
-  visitor_->OnSettings(clear_persisted);
+void SpdyFramerVisitorAdapter::OnSettings() {
+  visitor_->OnSettings();
 }
 
 void SpdyFramerVisitorAdapter::OnSettingsAck() {
diff --git a/net/spdy/core/spdy_framer_decoder_adapter.h b/net/spdy/core/spdy_framer_decoder_adapter.h
index ab188bd..dda9d8e 100644
--- a/net/spdy/core/spdy_framer_decoder_adapter.h
+++ b/net/spdy/core/spdy_framer_decoder_adapter.h
@@ -118,7 +118,7 @@
   void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override;
   void OnSetting(SpdySettingsIds id, uint32_t value) override;
   void OnPing(SpdyPingId unique_id, bool is_ack) override;
-  void OnSettings(bool clear_persisted) override;
+  void OnSettings() override;
   void OnSettingsAck() override;
   void OnSettingsEnd() override;
   void OnGoAway(SpdyStreamId last_accepted_stream_id,
diff --git a/net/spdy/core/spdy_framer_test.cc b/net/spdy/core/spdy_framer_test.cc
index 1002192f..e85b1f2 100644
--- a/net/spdy/core/spdy_framer_test.cc
+++ b/net/spdy/core/spdy_framer_test.cc
@@ -4051,7 +4051,7 @@
     if (flags & SETTINGS_FLAG_ACK) {
       EXPECT_CALL(visitor, OnError(_));
     } else {
-      EXPECT_CALL(visitor, OnSettings(flags & SETTINGS_FLAG_ACK));
+      EXPECT_CALL(visitor, OnSettings());
       EXPECT_CALL(visitor, OnSetting(SETTINGS_INITIAL_WINDOW_SIZE, 16));
       EXPECT_CALL(visitor, OnSettingsEnd());
     }
diff --git a/net/spdy/core/spdy_protocol.h b/net/spdy/core/spdy_protocol.h
index af3c1f1..ba4d2c3 100644
--- a/net/spdy/core/spdy_protocol.h
+++ b/net/spdy/core/spdy_protocol.h
@@ -123,11 +123,6 @@
   PUSH_PROMISE_FLAG_PADDED = 0x08,
 };
 
-// Flags on the SETTINGS control frame.
-enum SpdySettingsControlFlags {
-  SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS = 0x01,
-};
-
 enum Http2SettingsControlFlags {
   SETTINGS_FLAG_ACK = 0x01,
 };
diff --git a/printing/android/java/src/org/chromium/printing/Printable.java b/printing/android/java/src/org/chromium/printing/Printable.java
index 25c0ab2..67ac5d3 100644
--- a/printing/android/java/src/org/chromium/printing/Printable.java
+++ b/printing/android/java/src/org/chromium/printing/Printable.java
@@ -11,7 +11,7 @@
  */
 public interface Printable {
     /** Start the PDF generation process. */
-    boolean print();
+    boolean print(int renderProcessId, int renderFrameId);
 
     /** Get the title of the generated PDF document. */
     String getTitle();
diff --git a/printing/android/java/src/org/chromium/printing/PrintingController.java b/printing/android/java/src/org/chromium/printing/PrintingController.java
index 0bf1d15..9209085 100644
--- a/printing/android/java/src/org/chromium/printing/PrintingController.java
+++ b/printing/android/java/src/org/chromium/printing/PrintingController.java
@@ -82,8 +82,12 @@
      * @param printable An object capable of starting native side PDF generation, i.e. typically
      *     a Tab.
      * @param printManager The print manager that manages the print job.
+     * @param renderProcessId
+     * @param renderFrameId renderProcessId and renderFrameId are a pair of integers used to figure
+     *                      out which frame is going to be printed in native side.
      */
-    void setPendingPrint(final Printable printable, final PrintManagerDelegate printManager);
+    void setPendingPrint(final Printable printable, final PrintManagerDelegate printManager,
+            final int renderProcessId, final int renderFrameId);
 
     /**
      * Starts printing, provided that the current object already has sufficient data to start the
diff --git a/printing/android/java/src/org/chromium/printing/PrintingControllerImpl.java b/printing/android/java/src/org/chromium/printing/PrintingControllerImpl.java
index 50d1f24..a3dc255 100644
--- a/printing/android/java/src/org/chromium/printing/PrintingControllerImpl.java
+++ b/printing/android/java/src/org/chromium/printing/PrintingControllerImpl.java
@@ -54,6 +54,8 @@
      * with javascript.
      */
     private PrintingContextInterface mContextFromScriptInitiation;
+    private int mRenderProcessId;
+    private int mRenderFrameId;
 
     /** The file descriptor into which the PDF will be written.  Provided by the framework. */
     private int mFileDescriptor;
@@ -90,8 +92,8 @@
 
     private PrintManagerDelegate mPrintManager;
 
-    private PrintingControllerImpl(PrintDocumentAdapterWrapper printDocumentAdapterWrapper,
-                                   String errorText) {
+    private PrintingControllerImpl(
+            PrintDocumentAdapterWrapper printDocumentAdapterWrapper, String errorText) {
         mErrorMessage = errorText;
         mPrintDocumentAdapterWrapper = printDocumentAdapterWrapper;
         mPrintDocumentAdapterWrapper.setPdfGenerator(this);
@@ -172,13 +174,16 @@
     }
 
     @Override
-    public void setPendingPrint(final Printable printable, PrintManagerDelegate printManager) {
+    public void setPendingPrint(final Printable printable, PrintManagerDelegate printManager,
+            int renderProcessId, int renderFrameId) {
         if (mIsBusy) {
             Log.d(TAG, "Pending print can't be set. PrintingController is busy.");
             return;
         }
         mPrintable = printable;
         mPrintManager = printManager;
+        mRenderProcessId = renderProcessId;
+        mRenderFrameId = renderFrameId;
     }
 
     @Override
@@ -199,7 +204,7 @@
     @Override
     public void startPrint(final Printable printable, PrintManagerDelegate printManager) {
         if (mIsBusy) return;
-        setPendingPrint(printable, printManager);
+        setPendingPrint(printable, printManager, mRenderProcessId, mRenderFrameId);
         startPendingPrint(null);
     }
 
@@ -270,7 +275,9 @@
         mFileDescriptor = destination.getFd();
         mPages = convertPageRangesToIntegerArray(ranges);
 
-        if (mPrintable.print()) {
+        // mRenderProcessId and mRenderFrameId could be invalid values, in this case we are going to
+        // print the main frame.
+        if (mPrintable.print(mRenderProcessId, mRenderFrameId)) {
             mPrintingState = PRINTING_STATE_STARTED_FROM_ONWRITE;
         } else {
             mOnWriteCallback.onWriteFailed(mErrorMessage);
@@ -302,6 +309,8 @@
             mContextFromScriptInitiation.showSystemDialogDone();
             mContextFromScriptInitiation = null;
         }
+        mRenderProcessId = -1;
+        mRenderFrameId = -1;
 
         mPrintingState = PRINTING_STATE_FINISHED;
 
diff --git a/remoting/android/java/AndroidManifest.xml.jinja2 b/remoting/android/java/AndroidManifest.xml.jinja2
index 01cb776..62a7e365 100644
--- a/remoting/android/java/AndroidManifest.xml.jinja2
+++ b/remoting/android/java/AndroidManifest.xml.jinja2
@@ -9,7 +9,7 @@
 
     <application android:label="@string/product_name_android"
             android:name="org.chromium.chromoting.RemotingApplication"
-            android:icon="@mipmap/logo_remote_desktop_launcher"
+            android:icon="@mipmap/ic_launcher"
             android:theme="@style/BaseTheme"
             android:allowBackup="false"
             android:resizeableActivity="true"
diff --git a/remoting/android/java/res/mipmap-anydpi-v26/ic_launcher.xml b/remoting/android/java/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 0000000..036d09bc5
--- /dev/null
+++ b/remoting/android/java/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+    <background android:drawable="@color/ic_launcher_background"/>
+    <foreground android:drawable="@mipmap/ic_launcher_foreground"/>
+</adaptive-icon>
\ No newline at end of file
diff --git a/remoting/android/java/res/mipmap-hdpi/logo_remote_desktop_launcher.png b/remoting/android/java/res/mipmap-hdpi/ic_launcher.png
similarity index 100%
rename from remoting/android/java/res/mipmap-hdpi/logo_remote_desktop_launcher.png
rename to remoting/android/java/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/remoting/android/java/res/mipmap-hdpi/ic_launcher_foreground.png b/remoting/android/java/res/mipmap-hdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..b44234e
--- /dev/null
+++ b/remoting/android/java/res/mipmap-hdpi/ic_launcher_foreground.png
Binary files differ
diff --git a/remoting/android/java/res/mipmap-mdpi/logo_remote_desktop_launcher.png b/remoting/android/java/res/mipmap-mdpi/ic_launcher.png
similarity index 100%
rename from remoting/android/java/res/mipmap-mdpi/logo_remote_desktop_launcher.png
rename to remoting/android/java/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/remoting/android/java/res/mipmap-mdpi/ic_launcher_foreground.png b/remoting/android/java/res/mipmap-mdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..2e3d9db
--- /dev/null
+++ b/remoting/android/java/res/mipmap-mdpi/ic_launcher_foreground.png
Binary files differ
diff --git a/remoting/android/java/res/mipmap-xhdpi/logo_remote_desktop_launcher.png b/remoting/android/java/res/mipmap-xhdpi/ic_launcher.png
similarity index 100%
rename from remoting/android/java/res/mipmap-xhdpi/logo_remote_desktop_launcher.png
rename to remoting/android/java/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/remoting/android/java/res/mipmap-xhdpi/ic_launcher_foreground.png b/remoting/android/java/res/mipmap-xhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..837faa79
--- /dev/null
+++ b/remoting/android/java/res/mipmap-xhdpi/ic_launcher_foreground.png
Binary files differ
diff --git a/remoting/android/java/res/mipmap-xxhdpi/logo_remote_desktop_launcher.png b/remoting/android/java/res/mipmap-xxhdpi/ic_launcher.png
similarity index 100%
rename from remoting/android/java/res/mipmap-xxhdpi/logo_remote_desktop_launcher.png
rename to remoting/android/java/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/remoting/android/java/res/mipmap-xxhdpi/ic_launcher_foreground.png b/remoting/android/java/res/mipmap-xxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..66f025e
--- /dev/null
+++ b/remoting/android/java/res/mipmap-xxhdpi/ic_launcher_foreground.png
Binary files differ
diff --git a/remoting/android/java/res/mipmap-xxxhdpi/logo_remote_desktop_launcher.png b/remoting/android/java/res/mipmap-xxxhdpi/ic_launcher.png
similarity index 100%
rename from remoting/android/java/res/mipmap-xxxhdpi/logo_remote_desktop_launcher.png
rename to remoting/android/java/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/remoting/android/java/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/remoting/android/java/res/mipmap-xxxhdpi/ic_launcher_foreground.png
new file mode 100644
index 0000000..1c97050
--- /dev/null
+++ b/remoting/android/java/res/mipmap-xxxhdpi/ic_launcher_foreground.png
Binary files differ
diff --git a/remoting/android/java/res/values/ic_launcher_background.xml b/remoting/android/java/res/values/ic_launcher_background.xml
new file mode 100644
index 0000000..16cdd5aa
--- /dev/null
+++ b/remoting/android/java/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+  <color name="ic_launcher_background">#FFFFFF</color>
+</resources>
\ No newline at end of file
diff --git a/remoting/ios/app/client_connection_view_controller.mm b/remoting/ios/app/client_connection_view_controller.mm
index ec589b0..a9cdc9f1 100644
--- a/remoting/ios/app/client_connection_view_controller.mm
+++ b/remoting/ios/app/client_connection_view_controller.mm
@@ -59,11 +59,15 @@
   SessionErrorCode _lastError;
   HostInfo* _hostInfo;
 }
+
+@property(nonatomic, assign) SessionErrorCode lastError;
+
 @end
 
 @implementation ClientConnectionViewController
 
 @synthesize state = _state;
+@synthesize lastError = _lastError;
 
 - (instancetype)initWithHostInfo:(HostInfo*)hostInfo {
   self = [super init];
@@ -374,16 +378,24 @@
 
 - (void)attemptConnectionToHost {
   _client = [[RemotingClient alloc] init];
+  __weak ClientConnectionViewController* weakSelf = self;
   __weak RemotingClient* weakClient = _client;
   __weak HostInfo* weakHostInfo = _hostInfo;
   [RemotingService.instance.authentication
       callbackWithAccessToken:^(RemotingAuthenticationStatus status,
                                 NSString* userEmail, NSString* accessToken) {
-        [weakClient connectToHost:weakHostInfo
-                         username:userEmail
-                      accessToken:accessToken];
+        if (status == RemotingAuthenticationStatusSuccess) {
+          [weakClient connectToHost:weakHostInfo
+                           username:userEmail
+                        accessToken:accessToken];
+        } else {
+          LOG(ERROR) << "Failed to fetch access token for connectToHost. ("
+                     << status << ")";
+          weakSelf.lastError = SessionErrorOAuthTokenInvalid;
+          weakSelf.state = ClientViewError;
+        }
       }];
-  [self setState:ClientViewConnecting];
+  self.state = ClientViewConnecting;
 }
 
 - (void)showConnectingState {
@@ -524,6 +536,11 @@
       message = [MDCSnackbarMessage
           messageWithText:@"Error: SessionErrorUnknownError."];
       break;
+    case SessionErrorOAuthTokenInvalid:
+      message = [MDCSnackbarMessage
+          messageWithText:
+              @"Error: SessionErrorOAuthTokenInvalid. Please login again."];
+      break;
   }
   if (message.text) {
     [MDCSnackbarManager showMessage:message];
@@ -586,7 +603,7 @@
   }
   _lastError = sessionDetails.error;
   [[NSOperationQueue mainQueue] addOperationWithBlock:^{
-    [self setState:state];
+    self.state = state;
   }];
 }
 
diff --git a/remoting/ios/domain/client_session_details.h b/remoting/ios/domain/client_session_details.h
index b52f7df..afb9e0b 100644
--- a/remoting/ios/domain/client_session_details.h
+++ b/remoting/ios/domain/client_session_details.h
@@ -38,6 +38,7 @@
   SessionErrorMaxSessionLength,
   SessionErrorHostConfigurationError,
   SessionErrorUnknownError,
+  SessionErrorOAuthTokenInvalid,  // Custom for app.
 };
 
 // The current state of a session and data needed for session context.
diff --git a/remoting/ios/facade/host_list_fetcher.cc b/remoting/ios/facade/host_list_fetcher.cc
index ea3340ef..efb27f9 100644
--- a/remoting/ios/facade/host_list_fetcher.cc
+++ b/remoting/ios/facade/host_list_fetcher.cc
@@ -128,7 +128,8 @@
     hostlist.clear();
   }
   std::sort(hostlist.begin(), hostlist.end(), &compareHost);
-  base::ResetAndReturn(&hostlist_callback_).Run(hostlist);
+  base::ResetAndReturn(&hostlist_callback_)
+      .Run(request_->GetResponseCode(), hostlist);
 }
 
 }  // namespace remoting
diff --git a/remoting/ios/facade/host_list_fetcher.h b/remoting/ios/facade/host_list_fetcher.h
index 3e89bac..549abb8 100644
--- a/remoting/ios/facade/host_list_fetcher.h
+++ b/remoting/ios/facade/host_list_fetcher.h
@@ -38,7 +38,8 @@
 
   // Supplied by the client for each hostlist request and returns a valid,
   // initialized Hostlist object on success.
-  typedef base::Callback<void(const std::vector<remoting::HostInfo>& hostlist)>
+  typedef base::Callback<void(int response_code,
+                              const std::vector<remoting::HostInfo>& hostlist)>
       HostlistCallback;
 
   // Makes a service call to retrieve a hostlist. The
diff --git a/remoting/ios/facade/remoting_oauth_authentication.mm b/remoting/ios/facade/remoting_oauth_authentication.mm
index f5b93137..5bbbbf04 100644
--- a/remoting/ios/facade/remoting_oauth_authentication.mm
+++ b/remoting/ios/facade/remoting_oauth_authentication.mm
@@ -12,6 +12,7 @@
 #import <Security/Security.h>
 
 #import "base/mac/bind_objc_block.h"
+#import "ios/third_party/material_components_ios/src/components/Snackbar/src/MaterialSnackbar.h"
 #import "remoting/ios/facade/host_info.h"
 #import "remoting/ios/facade/host_list_fetcher.h"
 #import "remoting/ios/facade/ios_client_runtime_delegate.h"
@@ -142,7 +143,10 @@
     } else {
       LOG(ERROR) << "Failed to fetch access token from authorization code. ("
                  << status << ")";
-      // TODO(nicholss): Deal with the sad path for a bad auth token.
+      [MDCSnackbarManager
+          showMessage:
+              [MDCSnackbarMessage
+                  messageWithText:@"Authentication Failed. Please try again."]];
     }
   }];
 }
diff --git a/remoting/ios/facade/remoting_service.mm b/remoting/ios/facade/remoting_service.mm
index ba202b5..2330409 100644
--- a/remoting/ios/facade/remoting_service.mm
+++ b/remoting/ios/facade/remoting_service.mm
@@ -12,6 +12,7 @@
 #import <Security/Security.h>
 
 #import "base/mac/bind_objc_block.h"
+#import "ios/third_party/material_components_ios/src/components/Snackbar/src/MaterialSnackbar.h"
 #import "remoting/ios/domain/host_info.h"
 #import "remoting/ios/domain/user_info.h"
 #import "remoting/ios/facade/host_info.h"
@@ -23,6 +24,7 @@
 #include "base/i18n/time_formatting.h"
 #include "base/logging.h"
 #include "base/strings/sys_string_conversions.h"
+#include "net/http/http_status_code.h"
 #include "net/url_request/url_request_context_getter.h"
 #include "remoting/base/oauth_token_getter.h"
 #include "remoting/base/oauth_token_getter_impl.h"
@@ -85,7 +87,15 @@
   }
   _hostListFetcher->RetrieveHostlist(
       base::SysNSStringToUTF8(accessToken),
-      base::BindBlockArc(^(const std::vector<remoting::HostInfo>& hostlist) {
+      base::BindBlockArc(^(int responseCode,
+                           const std::vector<remoting::HostInfo>& hostlist) {
+
+        if (responseCode == net::HTTP_UNAUTHORIZED) {
+          [[RemotingService instance].authentication logout];
+        }
+        // TODO(nicholss): There are more |responseCode|s that we might want to
+        // trigger on, look into that later.
+
         NSMutableArray<HostInfo*>* hosts =
             [NSMutableArray arrayWithCapacity:hostlist.size()];
         std::string status;
@@ -173,14 +183,17 @@
             [self startHostListFetchWith:accessToken];
             break;
           case RemotingAuthenticationStatusNetworkError:
-            NSLog(
-                @"TODO(nicholss): implement this, "
-                @"RemotingAuthenticationStatusNetworkError.");
+            [MDCSnackbarManager
+                showMessage:
+                    [MDCSnackbarMessage
+                        messageWithText:@"[Network Error] Please try again."]];
             break;
           case RemotingAuthenticationStatusAuthError:
-            NSLog(
-                @"TODO(nicholss): implement this, "
-                @"RemotingAuthenticationStatusAuthError.");
+            [MDCSnackbarManager
+                showMessage:
+                    [MDCSnackbarMessage
+                        messageWithText:
+                            @"[Authentication Failed] Please login again."]];
             break;
         }
       }];
diff --git a/services/metrics/public/cpp/ukm_recorder.h b/services/metrics/public/cpp/ukm_recorder.h
index fcefa5b..ef1802f 100644
--- a/services/metrics/public/cpp/ukm_recorder.h
+++ b/services/metrics/public/cpp/ukm_recorder.h
@@ -20,6 +20,7 @@
 
 class ContextualSearchRankerLoggerImpl;
 class PluginInfoMessageFilter;
+class ProcessMemoryMetricsEmitter;
 class UkmPageLoadMetricsObserver;
 class LocalNetworkRequestsPageLoadMetricsObserver;
 
@@ -89,6 +90,7 @@
   friend autofill::AutofillMetrics;
   friend payments::JourneyLogger;
   friend ContextualSearchRankerLoggerImpl;
+  friend ProcessMemoryMetricsEmitter;
   friend PluginInfoMessageFilter;
   friend UkmPageLoadMetricsObserver;
   friend LocalNetworkRequestsPageLoadMetricsObserver;
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index a4692e8..7b75a07 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -222,6 +222,8 @@
     "ext/event_tracer_impl.h",
     "ext/fontmgr_default_android.cc",
     "ext/fontmgr_default_android.h",
+    "ext/fontmgr_default_fuchsia.cc",
+    "ext/fontmgr_default_fuchsia.h",
     "ext/fontmgr_default_linux.cc",
     "ext/fontmgr_default_linux.h",
     "ext/fontmgr_default_win.cc",
@@ -267,6 +269,13 @@
     ]
   }
 
+  if (!is_fuchsia) {
+    sources -= [
+      "ext/fontmgr_default_fuchsia.cc",
+      "ext/fontmgr_default_fuchsia.h",
+    ]
+  }
+
   # The imported Skia gni source paths are made absolute by gn.
   sources += skia_core_sources
   sources += skia_effects_sources
diff --git a/skia/config/SkUserConfig.h b/skia/config/SkUserConfig.h
index 2f5fc2bbc..f999f64 100644
--- a/skia/config/SkUserConfig.h
+++ b/skia/config/SkUserConfig.h
@@ -212,6 +212,10 @@
 #   define SK_USE_LEGACY_DISTANCE_FIELDS
 #endif
 
+#ifndef SK_SUPPORT_LEGACY_INDEX_8_COLORTYPE
+#define SK_SUPPORT_LEGACY_INDEX_8_COLORTYPE
+#endif
+
 #ifndef SK_DISABLE_DEFERRED_PROXIES
 #define SK_DISABLE_DEFERRED_PROXIES
 #endif
@@ -224,10 +228,6 @@
 #define SK_SUPPORT_NONSTD_BLENDMODES
 #endif
 
-#ifndef SK_SUPPORT_LEGACY_BILERP_IGNORING_HACK
-#define SK_SUPPORT_LEGACY_BILERP_IGNORING_HACK
-#endif
-
 #ifndef SK_SUPPORT_LEGACY_MASK_BLUR
 #define SK_SUPPORT_LEGACY_MASK_BLUR
 #endif
diff --git a/skia/ext/fontmgr_default_fuchsia.cc b/skia/ext/fontmgr_default_fuchsia.cc
new file mode 100644
index 0000000..06c583ef
--- /dev/null
+++ b/skia/ext/fontmgr_default_fuchsia.cc
@@ -0,0 +1,23 @@
+// 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 "skia/ext/fontmgr_default_fuchsia.h"
+
+#include "third_party/skia/include/ports/SkFontMgr.h"
+#include "third_party/skia/include/ports/SkFontMgr_android.h"
+
+namespace {
+// An owning leaky bare pointer.
+SkFontMgr* g_default_fontmgr = nullptr;
+}  // namespace
+
+SK_API void SetDefaultSkiaFactory(sk_sp<SkFontMgr> fontmgr) {
+  SkASSERT(g_default_fontmgr == nullptr);
+  g_default_fontmgr = fontmgr.release();
+}
+
+SK_API sk_sp<SkFontMgr> SkFontMgr::Factory() {
+  // TODO(fuchsia): Implement SkFontMgr.
+  return g_default_fontmgr ? sk_ref_sp(g_default_fontmgr) : nullptr;
+}
diff --git a/skia/ext/fontmgr_default_fuchsia.h b/skia/ext/fontmgr_default_fuchsia.h
new file mode 100644
index 0000000..a7a8e3a
--- /dev/null
+++ b/skia/ext/fontmgr_default_fuchsia.h
@@ -0,0 +1,16 @@
+// 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 SKIA_EXT_FONTMGR_DEFAULT_FUCHSIA_H_
+#define SKIA_EXT_FONTMGR_DEFAULT_FUCHSIA_H_
+
+#include "third_party/skia/include/core/SkTypes.h"
+
+class SkFontMgr;
+template <typename T>
+class sk_sp;
+
+SK_API void SetDefaultSkiaFactory(sk_sp<SkFontMgr> fontmgr);
+
+#endif  // SKIA_EXT_FONTMGR_DEFAULT_FUCHSIA_H_
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 52d4113..b58642b3d 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -10818,7 +10818,8 @@
   "Fuchsia": {
     "additional_compile_targets": [
       "d8",
-      "net_unittests"
+      "net_unittests",
+      "skia_unittests"
     ],
     "gtest_tests": [
       {
@@ -10844,7 +10845,8 @@
   "Fuchsia (dbg)": {
     "additional_compile_targets": [
       "d8",
-      "net_unittests"
+      "net_unittests",
+      "skia_unittests"
     ],
     "gtest_tests": [
       {
diff --git a/testing/buildbot/filters/OWNERS b/testing/buildbot/filters/OWNERS
index 5f8334b..fb790df 100644
--- a/testing/buildbot/filters/OWNERS
+++ b/testing/buildbot/filters/OWNERS
@@ -10,5 +10,11 @@
 per-file browser-side-navigation*=scottmg@chromium.org
 per-file browser-side-navigation*=yzshen@chromium.org
 
+per-file fuchsia*=jamesr@chromium.org
+per-file fuchsia*=kmarshall@chromium.org
+per-file fuchsia*=scottmg@chromium.org
+per-file fuchsia*=sergeyu@chromium.org
+per-file fuchsia*=wez@chromium.org
+
 # TEAM: infra-dev@chromium.org
 # COMPONENT: Infra>Client>Chrome
diff --git a/testing/buildbot/filters/fuchsia.base_unittests.filter b/testing/buildbot/filters/fuchsia.base_unittests.filter
index 790bf9b..f97655e 100644
--- a/testing/buildbot/filters/fuchsia.base_unittests.filter
+++ b/testing/buildbot/filters/fuchsia.base_unittests.filter
@@ -128,3 +128,6 @@
 
 # TaskScheduler is racy, causing bot instability: https://crbug.com/735701.
 -*TaskScheduler*
+
+# CancelableSyncSocket tests fail: http://crbug.com/741783
+-CancelableSyncSocket*
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index bfd707f..b8e2a39 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1085,6 +1085,26 @@
             ]
         }
     ],
+    "ExpectCTDynamic": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "ios",
+                "linux",
+                "mac",
+                "win"
+            ],
+            "experiments": [
+                {
+                    "name": "DynamicExpectCTEnabled",
+                    "enable_features": [
+                        "DynamicExpectCT"
+                    ]
+                }
+            ]
+        }
+    ],
     "ExpectCTReporting": [
         {
             "platforms": [
diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
index f6abf57a..ff583da5 100644
--- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
+++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-features=NetworkService
@@ -105,6 +105,7 @@
 Bug(none) compositing/reflections/load-video-in-reflection.html [ Failure ]
 Bug(none) compositing/self-painting-layers.html [ Failure ]
 Bug(none) compositing/self-painting-layers2.html [ Timeout ]
+Bug(none) compositing/video-frame-size-change.html [ Timeout ]
 Bug(none) compositing/video/video-reflection.html [ Timeout ]
 Bug(none) compositing/visibility/visibility-simple-video-layer.html [ Failure ]
 Bug(none) crypto/gc.html [ Timeout ]
@@ -182,71 +183,9 @@
 Bug(none) editing/inserting/insert-html-crash.html [ Timeout ]
 Bug(none) editing/style/apply-style-join-child-text-nodes-crash.html [ Timeout ]
 Bug(none) external/wpt/2dcontext/imagebitmap/createImageBitmap-drawImage.html [ Crash Failure Timeout ]
-Bug(none) external/wpt/FileAPI/blob/Blob-XHR-revoke.html [ Failure Timeout ]
-Bug(none) external/wpt/FileAPI/blob/Blob-constructor.html [ Failure Timeout ]
-Bug(none) external/wpt/FileAPI/blob/Blob-slice.html [ Failure Timeout ]
-Bug(none) external/wpt/FileAPI/file/File-constructor.html [ Failure Timeout ]
 Bug(none) external/wpt/FileAPI/historical.https.html [ Failure Timeout ]
-Bug(none) external/wpt/FileAPI/reading-data-section/Determining-Encoding.html [ Failure Timeout ]
-Bug(none) external/wpt/FileAPI/reading-data-section/FileReader-multiple-reads.html [ Failure Timeout ]
-Bug(none) external/wpt/FileAPI/reading-data-section/filereader_abort.html [ Failure Timeout ]
-Bug(none) external/wpt/FileAPI/reading-data-section/filereader_readAsArrayBuffer.html [ Failure Timeout ]
-Bug(none) external/wpt/FileAPI/reading-data-section/filereader_readAsDataURL.html [ Failure Timeout ]
-Bug(none) external/wpt/FileAPI/reading-data-section/filereader_readAsText.html [ Failure Timeout ]
-Bug(none) external/wpt/FileAPI/reading-data-section/filereader_result.html [ Failure Timeout ]
-Bug(none) external/wpt/FileAPI/url/blob-url-in-sandboxed-iframe.html [ Failure Timeout ]
 Bug(none) external/wpt/FileAPI/url/url_xmlhttprequest.html [ Crash Failure Timeout ]
 Bug(none) external/wpt/IndexedDB [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/derive_bits_keys/test_ecdh_bits.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/derive_bits_keys/test_ecdh_keys.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/derive_bits_keys/test_hkdf.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/derive_bits_keys/test_pbkdf2_empty_empty.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/derive_bits_keys/test_pbkdf2_empty_long.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/derive_bits_keys/test_pbkdf2_empty_short.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/derive_bits_keys/test_pbkdf2_long_empty.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/derive_bits_keys/test_pbkdf2_long_long.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/derive_bits_keys/test_pbkdf2_long_short.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/derive_bits_keys/test_pbkdf2_short_empty.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/derive_bits_keys/test_pbkdf2_short_long.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/derive_bits_keys/test_pbkdf2_short_short.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/digest/test_digest.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/encrypt_decrypt/test_aes_cbc.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/encrypt_decrypt/test_aes_ctr.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/encrypt_decrypt/test_aes_gcm.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/encrypt_decrypt/test_rsa_oaep.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_aes-cbc.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_aes-ctr.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_failures.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_failures_AES-CBC.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_failures_AES-CTR.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_failures_AES-GCM.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_failures_AES-KW.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_failures_ECDH.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_failures_ECDSA.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_failures_HMAC.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_failures_RSA-OAEP.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_failures_RSA-PSS.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_failures_RSASSA-PKCS1-v1_5.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_successes_AES-CBC.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_successes_AES-CTR.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_successes_AES-GCM.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_successes_AES-KW.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_successes_ECDH.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_successes_ECDSA.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_successes_HMAC.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_successes_RSA-OAEP.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_successes_RSA-PSS.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/generateKey/test_successes_RSASSA-PKCS1-v1_5.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/import_export/test_ec_importKey.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/import_export/test_rsa_importKey.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/import_export/test_symmetric_importKey.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/secure_context/crypto-subtle-non-secure-context-not-available.sub.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/secure_context/crypto-subtle-secure-context-available.https.sub.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/sign_verify/test_ecdsa.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/sign_verify/test_hmac.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/sign_verify/test_rsa_pkcs.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/sign_verify/test_rsa_pss.https.html [ Failure Timeout ]
-Bug(none) external/wpt/WebCryptoAPI/wrapKey_unwrapKey/test_wrapKey_unwrapKey.https.html [ Failure Timeout ]
 Bug(none) external/wpt/WebIDL/ecmascript-binding/es-exceptions/exceptions.html [ Failure Timeout ]
 Bug(none) external/wpt/WebIDL/ecmascript-binding/has-instance.html [ Failure Timeout ]
 Bug(none) external/wpt/XMLHttpRequest [ Crash Failure Timeout ]
@@ -263,7 +202,6 @@
 Bug(none) external/wpt/beacon/headers/header-referrer-strict-origin.https.html [ Failure Timeout ]
 Bug(none) external/wpt/beacon/headers/header-referrer-unsafe-url.https.html [ Failure Timeout ]
 Bug(none) external/wpt/clear-site-data/navigation.https.html [ Timeout ]
-Bug(none) external/wpt/clipboard-apis [ Timeout ]
 Bug(none) external/wpt/content-security-policy/child-src/child-src-about-blank-allowed-by-default.sub.html [ Failure Timeout ]
 Bug(none) external/wpt/content-security-policy/child-src/child-src-about-blank-allowed-by-scheme.sub.html [ Failure Timeout ]
 Bug(none) external/wpt/content-security-policy/child-src/child-src-allowed.sub.html [ Failure Timeout ]
@@ -329,35 +267,11 @@
 Bug(none) external/wpt/cors/request-headers.htm [ Failure Timeout ]
 Bug(none) external/wpt/cors/response-headers.htm [ Failure Timeout ]
 Bug(none) external/wpt/cors/simple-requests.htm [ Failure Timeout ]
-Bug(none) external/wpt/credential-management/credentialscontainer-create-basics.https.html [ Failure Timeout ]
-Bug(none) external/wpt/credential-management/idl.https.html [ Failure Timeout ]
 Bug(none) external/wpt/css-font-display/font-display.html [ Failure Timeout ]
 Bug(none) external/wpt/css/CSS2/floats-clear/floats-015.xht [ Failure Timeout ]
 Bug(none) external/wpt/css/css-grid-1/alignment/grid-content-distribution-018.html [ Failure Timeout ]
 Bug(none) external/wpt/css/css-shapes-1/shape-outside/shape-box/shape-outside-box-003.html [ Failure Timeout ]
 Bug(none) external/wpt/css/css-shapes-1/shape-outside/values/shape-outside-ellipse-004.html [ Failure Timeout ]
-Bug(none) external/wpt/css-paint-api/paint2d-zoom.html [ Crash Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-001.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-002.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-003.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-004.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-005.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-006.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-007.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-008.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-009.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-010.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-011.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-012.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-013.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-014.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-015.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-016.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/parse-input-arguments-017.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/registered-properties-in-custom-paint.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/style-background-image.html [ Timeout ]
-Bug(none) external/wpt/css-paint-api/style-before-pseudo.html [ Crash Pass Timeout ]
-Bug(none) external/wpt/css-paint-api/style-first-letter-pseudo.html [ Timeout ]
 Bug(none) external/wpt/cssom-view/scrolling-quirks-vs-nonquirks.html [ Failure Timeout ]
 Bug(none) external/wpt/cssom-view/scrollingElement.html [ Failure Timeout ]
 Bug(none) external/wpt/custom-elements/custom-element-registry/per-global.html [ Failure Timeout ]
@@ -367,37 +281,13 @@
 Bug(none) external/wpt/dom/nodes/Element-remove.html [ Failure Timeout ]
 Bug(none) external/wpt/domxpath/xml_xpath_runner.html [ Failure Timeout ]
 Bug(none) external/wpt/eventsource/dedicated-worker/eventsource-onopen.htm [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/basic/mode-no-cors-worker.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/basic/mode-no-cors.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/basic/scheme-blob-worker.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/basic/scheme-blob.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/basic/scheme-others-worker.html [ Failure Timeout ]
 Bug(none) external/wpt/fetch/api/policies/referrer-no-referrer-service-worker.https.html [ Failure Timeout ]
 Bug(none) external/wpt/fetch/api/policies/referrer-origin-service-worker.https.html [ Failure Timeout ]
 Bug(none) external/wpt/fetch/api/policies/referrer-origin-when-cross-origin-service-worker.https.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/policies/referrer-origin-when-cross-origin-worker.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/policies/referrer-origin-when-cross-origin.html [ Failure Timeout ]
 Bug(none) external/wpt/fetch/api/policies/referrer-unsafe-url-service-worker.https.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/redirect/redirect-location-worker.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/request/request-consume-empty.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/request/request-consume.html [ Crash Pass Failure Timeout ]
-Bug(none) external/wpt/fetch/api/request/request-init-002.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/response/response-cancel-stream.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/response/response-clone.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/response/response-consume-empty.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/response/response-consume-stream.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/response/response-consume.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/api/response/response-init-002.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/http-cache/vary.html [ Failure Timeout ]
-Bug(none) external/wpt/fetch/nosniff/importscripts.html [ Failure Timeout ]
 Bug(none) external/wpt/fullscreen/api/document-exit-fullscreen-active-document.html [ Failure Timeout ]
 Bug(none) external/wpt/fullscreen/api/document-fullscreen-enabled-active-document.html [ Failure Timeout ]
 Bug(none) external/wpt/fullscreen/api/element-request-fullscreen-active-document.html [ Failure Timeout ]
-Bug(none) external/wpt/geolocation-API/PositionOptions.https.html [ Failure Timeout ]
-Bug(none) external/wpt/geolocation-API/getCurrentPosition_IDL.https.html [ Failure Timeout ]
-Bug(none) external/wpt/geolocation-API/getCurrentPosition_permission_allow.https.html [ Failure Timeout ]
-Bug(none) external/wpt/geolocation-API/getCurrentPosition_permission_deny.https.html [ Failure Timeout ]
-Bug(none) external/wpt/geolocation-API/watchPosition_permission_deny.https.html [ Failure Timeout ]
 Bug(none) external/wpt/hr-time/test_cross_frame_start.html [ Failure Timeout ]
 Bug(none) external/wpt/hr-time/window-worker-time-origin.html [ Failure Timeout ]
 Bug(none) external/wpt/html/browsers/browsing-the-web/navigating-across-documents/012.html [ Failure Timeout ]
@@ -441,1032 +331,17 @@
 Bug(none) external/wpt/html/webappapis/scripting/processing-model-2/integration-with-the-javascript-agent-formalism/canblock-serviceworker.https.html [ Failure Timeout ]
 Bug(none) external/wpt/html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-events.serviceworker.https.html [ Failure Timeout ]
 Bug(none) external/wpt/html/webappapis/the-windoworworkerglobalscope-mixin/Worker_Self_Origin.html [ Failure Timeout ]
-Bug(none) external/wpt/keyboard-lock/idlharness.https.html [ Failure Timeout ]
-Bug(none) external/wpt/keyboard-lock/navigator-cancelKeyboardLock.https.html [ Failure Timeout ]
-Bug(none) external/wpt/keyboard-lock/navigator-requestKeyboardLock-two-parallel-requests.https.html [ Failure Timeout ]
-Bug(none) external/wpt/keyboard-lock/navigator-requestKeyboardLock-two-sequential-requests.https.html [ Failure Timeout ]
-Bug(none) external/wpt/keyboard-lock/navigator-requestKeyboardLock.https.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-activesourcebuffers.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-append-buffer.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-appendwindow.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-avtracks.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-buffered.html [ Failure Timeout ]
 Bug(none) external/wpt/media-source/mediasource-config-change-webm-a-bitrate.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-config-change-webm-av-audio-bitrate.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-config-change-webm-av-framesize.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-config-change-webm-av-video-bitrate.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-config-change-webm-v-bitrate.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-detach.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-duration-boundaryconditions.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-duration.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-endofstream.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-errors.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-liveseekable.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-play-then-seek-back.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-play.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-remove.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-removesourcebuffer.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-seek-beyond-duration.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-seek-during-pending-seek.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-seekable.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-sequencemode-append-buffer.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-sourcebuffer-mode.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-sourcebuffer-trackdefaults.html [ Failure Timeout ]
-Bug(none) external/wpt/media-source/mediasource-timestamp-offset.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/GUM-api.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/GUM-deny.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/GUM-empty-option-param.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/GUM-impossible-constraint.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/GUM-optional-constraint.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/GUM-trivial-constraint.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/GUM-unknownkey-option-param.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaDevices-enumerateDevices.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaDevices-getUserMedia.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaStream-MediaElement-preload-none.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaStream-MediaElement-srcObject.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaStream-add-audio-track.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaStream-audio-only.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaStream-finished-add.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaStream-gettrackid.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaStream-id-manual.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaStream-idl.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaStream-removetrack.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaStream-video-only.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaStreamTrack-MediaElement-disabled-video-is-black.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaStreamTrack-id.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaStreamTrack-init.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mediacapture-streams/MediaStreamTrackEvent-constructor.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/audio-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/audio-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/fetch-request/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/fetch-request/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/form-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/form-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/iframe-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/iframe-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/img-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/img-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/link-css-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/link-css-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/link-prefetch-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/link-prefetch-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/object-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/object-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/picture-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/picture-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/script-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/script-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/video-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/video-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/worker-request/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/worker-request/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/xhr-request/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-https/xhr-request/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
 Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-wss/websocket-request/top-level/keep-scheme-redirect/websocket-allowed.https.html [ Failure Timeout ]
 Bug(none) external/wpt/mixed-content/allowed/http-csp/same-host-wss/websocket-request/top-level/no-redirect/websocket-allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/meta-csp/same-host-https/audio-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/meta-csp/same-host-https/fetch-request/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/meta-csp/same-host-https/form-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/meta-csp/same-host-https/iframe-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/meta-csp/same-host-https/img-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/meta-csp/same-host-https/link-css-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/meta-csp/same-host-https/link-prefetch-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/meta-csp/same-host-https/object-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/meta-csp/same-host-https/picture-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/meta-csp/same-host-https/script-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/meta-csp/same-host-https/video-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/meta-csp/same-host-https/worker-request/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/meta-csp/same-host-https/xhr-request/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/meta-csp/same-host-wss/websocket-request/top-level/no-redirect/websocket-allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/audio-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/audio-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/fetch-request/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/fetch-request/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/form-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/form-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/iframe-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/iframe-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/img-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/img-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/link-css-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/link-css-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/link-prefetch-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/link-prefetch-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/object-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/object-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/picture-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/picture-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/script-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/script-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/video-tag/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/video-tag/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/worker-request/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/worker-request/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/xhr-request/top-level/keep-scheme-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-https/xhr-request/top-level/no-redirect/allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-wss/websocket-request/top-level/keep-scheme-redirect/websocket-allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/allowed/no-opt-in/same-host-wss/websocket-request/top-level/no-redirect/websocket-allowed.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/fetch-request/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/fetch-request/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/fetch-request/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/link-css-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/link-css-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/link-css-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/object-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/object-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/object-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/picture-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/picture-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/picture-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/script-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/script-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/script-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/worker-request/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/worker-request/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/worker-request/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/xhr-request/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/xhr-request/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-http/xhr-request/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-ws/websocket-request/top-level/keep-scheme-redirect/ws-downgrade-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-ws/websocket-request/top-level/no-redirect/ws-downgrade-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/cross-origin-ws/websocket-request/top-level/swap-scheme-redirect/ws-downgrade-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/fetch-request/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/fetch-request/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/fetch-request/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/link-css-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/link-css-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/link-css-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/object-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/object-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/object-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/picture-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/picture-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/picture-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/script-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/script-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/script-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/worker-request/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/worker-request/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/worker-request/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/xhr-request/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/xhr-request/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-http/xhr-request/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-ws/websocket-request/top-level/keep-scheme-redirect/ws-downgrade-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-ws/websocket-request/top-level/no-redirect/ws-downgrade-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/http-csp/same-host-ws/websocket-request/top-level/swap-scheme-redirect/ws-downgrade-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/cross-origin-http/fetch-request/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/cross-origin-http/link-css-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/cross-origin-http/object-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/cross-origin-http/picture-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/cross-origin-http/script-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/cross-origin-http/worker-request/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/cross-origin-http/xhr-request/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/cross-origin-ws/websocket-request/top-level/no-redirect/ws-downgrade-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/same-host-http/fetch-request/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/same-host-http/link-css-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/same-host-http/object-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/same-host-http/picture-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/same-host-http/script-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/same-host-http/worker-request/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/same-host-http/xhr-request/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/meta-csp/same-host-ws/websocket-request/top-level/no-redirect/ws-downgrade-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/fetch-request/top-level/keep-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/fetch-request/top-level/no-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/fetch-request/top-level/swap-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/link-css-tag/top-level/keep-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/link-css-tag/top-level/no-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/link-css-tag/top-level/swap-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/object-tag/top-level/keep-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/object-tag/top-level/no-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/object-tag/top-level/swap-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/picture-tag/top-level/keep-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/picture-tag/top-level/no-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/picture-tag/top-level/swap-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/script-tag/top-level/keep-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/script-tag/top-level/no-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/script-tag/top-level/swap-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/worker-request/top-level/keep-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/worker-request/top-level/no-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/worker-request/top-level/swap-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/xhr-request/top-level/keep-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/xhr-request/top-level/no-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-http/xhr-request/top-level/swap-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-ws/websocket-request/top-level/keep-scheme-redirect/ws-downgrade-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-ws/websocket-request/top-level/no-redirect/ws-downgrade-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/cross-origin-ws/websocket-request/top-level/swap-scheme-redirect/ws-downgrade-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/fetch-request/top-level/keep-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/fetch-request/top-level/no-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/fetch-request/top-level/swap-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/link-css-tag/top-level/keep-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/link-css-tag/top-level/no-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/link-css-tag/top-level/swap-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/object-tag/top-level/keep-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/object-tag/top-level/no-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/object-tag/top-level/swap-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/picture-tag/top-level/keep-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/picture-tag/top-level/no-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/picture-tag/top-level/swap-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/script-tag/top-level/keep-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/script-tag/top-level/no-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/script-tag/top-level/swap-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/worker-request/top-level/keep-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/worker-request/top-level/no-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/worker-request/top-level/swap-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/xhr-request/top-level/keep-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/xhr-request/top-level/no-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-http/xhr-request/top-level/swap-scheme-redirect/no-opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-ws/websocket-request/top-level/keep-scheme-redirect/ws-downgrade-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-ws/websocket-request/top-level/no-redirect/ws-downgrade-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/blockable/no-opt-in/same-host-ws/websocket-request/top-level/swap-scheme-redirect/ws-downgrade-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/imageset.https.sub.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/cross-origin-http/audio-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/cross-origin-http/audio-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/cross-origin-http/audio-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/cross-origin-http/img-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/cross-origin-http/img-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/cross-origin-http/img-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/cross-origin-http/link-prefetch-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/cross-origin-http/link-prefetch-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/cross-origin-http/link-prefetch-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/cross-origin-http/video-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/cross-origin-http/video-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/cross-origin-http/video-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/same-host-http/audio-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/same-host-http/audio-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/same-host-http/audio-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/same-host-http/img-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/same-host-http/img-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/same-host-http/img-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/same-host-http/link-prefetch-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/same-host-http/link-prefetch-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/same-host-http/link-prefetch-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/same-host-http/video-tag/top-level/keep-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/same-host-http/video-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/http-csp/same-host-http/video-tag/top-level/swap-scheme-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/meta-csp/cross-origin-http/audio-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/meta-csp/cross-origin-http/img-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/meta-csp/cross-origin-http/link-prefetch-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/meta-csp/cross-origin-http/video-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/meta-csp/same-host-http/audio-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/meta-csp/same-host-http/img-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/meta-csp/same-host-http/link-prefetch-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/meta-csp/same-host-http/video-tag/top-level/no-redirect/opt-in-blocks.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/cross-origin-http/audio-tag/top-level/keep-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/cross-origin-http/audio-tag/top-level/no-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/cross-origin-http/audio-tag/top-level/swap-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/cross-origin-http/img-tag/top-level/keep-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/cross-origin-http/img-tag/top-level/no-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/cross-origin-http/img-tag/top-level/swap-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/cross-origin-http/link-prefetch-tag/top-level/keep-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/cross-origin-http/link-prefetch-tag/top-level/no-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/cross-origin-http/link-prefetch-tag/top-level/swap-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/cross-origin-http/video-tag/top-level/keep-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/cross-origin-http/video-tag/top-level/no-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/cross-origin-http/video-tag/top-level/swap-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/same-host-http/audio-tag/top-level/keep-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/same-host-http/audio-tag/top-level/no-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/same-host-http/audio-tag/top-level/swap-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/same-host-http/img-tag/top-level/keep-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/same-host-http/img-tag/top-level/no-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/same-host-http/img-tag/top-level/swap-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/same-host-http/link-prefetch-tag/top-level/keep-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/same-host-http/link-prefetch-tag/top-level/no-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/same-host-http/link-prefetch-tag/top-level/swap-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/same-host-http/video-tag/top-level/keep-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/same-host-http/video-tag/top-level/no-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
-Bug(none) external/wpt/mixed-content/optionally-blockable/no-opt-in/same-host-http/video-tag/top-level/swap-scheme-redirect/no-opt-in-allows.https.html [ Failure Timeout ]
 Bug(none) external/wpt/navigation-timing/nav2_test_attributes_values.html [ Failure Timeout ]
 Bug(none) external/wpt/navigation-timing/nav2_test_unloadEvents_previous_document_cross_origin.sub.html [ Failure Timeout ]
 Bug(none) external/wpt/notifications/shownotification-resolve-manual.https.html [ Failure Timeout ]
 Bug(none) external/wpt/offscreen-canvas [ Crash Failure Timeout ]
 Bug(none) external/wpt/orientation-sensor/idlharness.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/allowpaymentrequest/active-document-cross-origin.https.sub.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/allowpaymentrequest/active-document-same-origin.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/allowpaymentrequest/basic.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/historical.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/interfaces.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/payment-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Timeout ]
-Bug(none) external/wpt/payment-request/payment-allowed-by-feature-policy-attribute.https.sub.html [ Timeout ]
-Bug(none) external/wpt/payment-request/payment-allowed-by-feature-policy.https.sub.html [ Timeout ]
-Bug(none) external/wpt/payment-request/payment-default-feature-policy.https.sub.html [ Timeout ]
-Bug(none) external/wpt/payment-request/payment-disabled-by-feature-policy.https.sub.html [ Timeout ] 
-Bug(none) external/wpt/payment-request/payment-request-abort-method.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/payment-request-constructor-crash.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/payment-request-constructor.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/payment-request-id.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/payment-request-onshippingaddresschange-attribute.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/payment-request-onshippingoptionchange-attribute.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/payment-request-show-method.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/payment-request-update-event-constructor.https.html [ Failure Timeout ]
-Bug(none) external/wpt/payment-request/payment-request-update-event-updatewith-method.https.html [ Timeout ]
 Bug(none) external/wpt/pointerevents/pointerevent_touch-action-table-test_touch-manual.html [ Failure Timeout ]
-Bug(none) external/wpt/preload/delaying-onload-link-preload-after-discovery.html [ Failure Timeout ]
-Bug(none) external/wpt/preload/download-resources.html [ Failure Timeout ]
 Bug(none) external/wpt/preload/fetch-destination.https.html [ Failure Timeout ]
-Bug(none) external/wpt/preload/link-header-preload.html [ Failure Timeout ]
-Bug(none) external/wpt/preload/onerror-event.html [ Failure Timeout ]
-Bug(none) external/wpt/preload/onload-event.html [ Failure Timeout ]
-Bug(none) external/wpt/preload/preload-csp.sub.html [ Failure Timeout ]
-Bug(none) external/wpt/preload/preload-default-csp.sub.html [ Failure Timeout ]
-Bug(none) external/wpt/preload/preload-with-type.html [ Failure Timeout ]
 Bug(none) external/wpt/preload/single-download-preload.html [ Failure Timeout ]
-Bug(none) external/wpt/presentation-api/controlling-ua/PresentationRequest_error.https.html [ Failure Timeout ]
-Bug(none) external/wpt/presentation-api/controlling-ua/PresentationRequest_mixedcontent.https.html [ Failure Timeout ]
-Bug(none) external/wpt/presentation-api/controlling-ua/PresentationRequest_mixedcontent_multiple.https.html [ Failure Timeout ]
-Bug(none) external/wpt/presentation-api/controlling-ua/PresentationRequest_sandboxing_error.https.html [ Failure Timeout ]
-Bug(none) external/wpt/presentation-api/controlling-ua/PresentationRequest_sandboxing_success.https.html [ Failure Timeout ]
-Bug(none) external/wpt/presentation-api/controlling-ua/PresentationRequest_success.https.html [ Failure Timeout ]
-Bug(none) external/wpt/presentation-api/controlling-ua/defaultRequest.https.html [ Failure Timeout ]
-Bug(none) external/wpt/presentation-api/controlling-ua/getAvailability_sandboxing_success.https.html [ Failure Timeout ]
-Bug(none) external/wpt/presentation-api/controlling-ua/idlharness.https.html [ Failure Timeout ]
-Bug(none) external/wpt/presentation-api/controlling-ua/reconnectToPresentation_notfound_error.https.html [ Failure Timeout ]
-Bug(none) external/wpt/presentation-api/controlling-ua/reconnectToPresentation_sandboxing_success.https.html [ Failure Timeout ]
-Bug(none) external/wpt/presentation-api/controlling-ua/startNewPresentation_error.https.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/attr-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/attr-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/attr-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/attr-referrer/cross-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/attr-referrer/cross-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/attr-referrer/cross-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/attr-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/attr-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/attr-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/attr-referrer/same-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/attr-referrer/same-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/attr-referrer/same-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/cross-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/http-rp/same-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/cross-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer-when-downgrade/meta-referrer/same-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/attr-referrer/cross-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/attr-referrer/cross-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/attr-referrer/cross-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/attr-referrer/cross-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/attr-referrer/cross-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/attr-referrer/cross-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/attr-referrer/same-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/attr-referrer/same-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/attr-referrer/same-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/attr-referrer/same-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/attr-referrer/same-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/attr-referrer/same-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/cross-origin/http-https/fetch-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/cross-origin/http-https/fetch-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/cross-origin/http-https/fetch-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/cross-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/cross-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/cross-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/cross-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/cross-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/cross-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/cross-origin/http-https/script-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/cross-origin/http-https/script-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/cross-origin/http-https/script-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/cross-origin/http-https/xhr-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/cross-origin/http-https/xhr-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/cross-origin/http-https/xhr-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-https/fetch-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-https/fetch-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-https/fetch-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-https/script-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-https/script-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-https/script-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-https/xhr-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-https/xhr-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/http-rp/same-origin/http-https/xhr-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/fetch-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/fetch-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/fetch-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/script-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/script-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/script-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/xhr-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/xhr-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/cross-origin/http-https/xhr-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-http/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/fetch-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/fetch-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/fetch-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/script-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/script-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/script-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/xhr-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/xhr-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/no-referrer/meta-referrer/same-origin/http-https/xhr-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/cross-origin/http-https/iframe-tag/cross-origin.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/cross-origin/http-https/iframe-tag/cross-origin.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/cross-origin/http-https/iframe-tag/cross-origin.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/cross-origin/http-https/img-tag/cross-origin.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/cross-origin/http-https/img-tag/cross-origin.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/cross-origin/http-https/img-tag/cross-origin.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/iframe-tag/same-origin-downgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/iframe-tag/same-origin-downgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/iframe-tag/same-origin-downgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/iframe-tag/same-origin-insecure.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/iframe-tag/same-origin-upgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/iframe-tag/same-origin-upgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/iframe-tag/same-origin-upgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/img-tag/same-origin-downgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/img-tag/same-origin-downgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/img-tag/same-origin-downgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/img-tag/same-origin-insecure.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/img-tag/same-origin-upgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/img-tag/same-origin-upgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/attr-referrer/same-origin/http-https/img-tag/same-origin-upgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/cross-origin/http-https/fetch-request/cross-origin.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/cross-origin/http-https/fetch-request/cross-origin.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/cross-origin/http-https/fetch-request/cross-origin.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/cross-origin/http-https/iframe-tag/cross-origin.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/cross-origin/http-https/iframe-tag/cross-origin.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/cross-origin/http-https/iframe-tag/cross-origin.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/cross-origin/http-https/img-tag/cross-origin.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/cross-origin/http-https/img-tag/cross-origin.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/cross-origin/http-https/img-tag/cross-origin.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/cross-origin/http-https/script-tag/cross-origin.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/cross-origin/http-https/script-tag/cross-origin.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/cross-origin/http-https/script-tag/cross-origin.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/cross-origin/http-https/xhr-request/cross-origin.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/cross-origin/http-https/xhr-request/cross-origin.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/cross-origin/http-https/xhr-request/cross-origin.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/iframe-tag/same-origin-insecure.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/img-tag/same-origin-insecure.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-http/script-tag/same-origin-insecure.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/same-origin-downgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/same-origin-downgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/same-origin-downgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/same-origin-insecure.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/same-origin-upgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/same-origin-upgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/same-origin-upgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/same-origin-downgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/same-origin-downgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/same-origin-downgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/same-origin-insecure.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/same-origin-upgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/same-origin-upgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/same-origin-upgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/same-origin-downgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/same-origin-downgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/same-origin-downgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/same-origin-insecure.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/same-origin-upgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/same-origin-upgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/same-origin-upgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/same-origin-downgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/same-origin-downgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/same-origin-downgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/same-origin-insecure.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/same-origin-upgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/same-origin-upgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/same-origin-upgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/same-origin-downgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/same-origin-downgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/same-origin-downgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/same-origin-insecure.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/same-origin-upgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/same-origin-upgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/same-origin-upgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/fetch-request/cross-origin.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/fetch-request/cross-origin.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/fetch-request/cross-origin.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/iframe-tag/cross-origin.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/iframe-tag/cross-origin.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/iframe-tag/cross-origin.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/img-tag/cross-origin.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/img-tag/cross-origin.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/img-tag/cross-origin.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/script-tag/cross-origin.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/script-tag/cross-origin.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/script-tag/cross-origin.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/xhr-request/cross-origin.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/xhr-request/cross-origin.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/cross-origin/http-https/xhr-request/cross-origin.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/fetch-request/same-origin-downgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/fetch-request/same-origin-downgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/fetch-request/same-origin-downgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/fetch-request/same-origin-insecure.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/fetch-request/same-origin-upgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/fetch-request/same-origin-upgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/fetch-request/same-origin-upgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/iframe-tag/same-origin-downgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/iframe-tag/same-origin-downgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/iframe-tag/same-origin-downgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/iframe-tag/same-origin-insecure.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/iframe-tag/same-origin-upgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/iframe-tag/same-origin-upgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/iframe-tag/same-origin-upgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/same-origin-downgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/same-origin-downgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/same-origin-downgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/same-origin-insecure.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/same-origin-upgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/same-origin-upgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/same-origin-upgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/script-tag/same-origin-downgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/script-tag/same-origin-downgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/script-tag/same-origin-downgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/script-tag/same-origin-insecure.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/script-tag/same-origin-upgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/script-tag/same-origin-upgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/script-tag/same-origin-upgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/xhr-request/same-origin-downgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/xhr-request/same-origin-downgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/xhr-request/same-origin-downgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/xhr-request/same-origin-insecure.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/xhr-request/same-origin-upgrade.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/xhr-request/same-origin-upgrade.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin-when-cross-origin/meta-referrer/same-origin/http-https/xhr-request/same-origin-upgrade.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/attr-referrer/cross-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/attr-referrer/cross-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/attr-referrer/cross-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/attr-referrer/cross-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/attr-referrer/cross-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/attr-referrer/cross-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/attr-referrer/same-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/attr-referrer/same-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/attr-referrer/same-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/attr-referrer/same-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/attr-referrer/same-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/attr-referrer/same-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-http/fetch-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-https/fetch-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-https/fetch-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-https/fetch-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-https/script-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-https/script-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-https/script-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-https/xhr-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-https/xhr-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/cross-origin/http-https/xhr-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/same-origin/http-https/fetch-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/same-origin/http-https/fetch-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/same-origin/http-https/fetch-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/same-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/same-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/same-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/same-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/same-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/same-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/same-origin/http-https/script-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/same-origin/http-https/script-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/same-origin/http-https/script-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/same-origin/http-https/xhr-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/same-origin/http-https/xhr-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/http-rp/same-origin/http-https/xhr-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-http/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-https/fetch-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-https/fetch-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-https/fetch-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-https/script-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-https/script-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-https/script-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-https/xhr-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-https/xhr-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/cross-origin/http-https/xhr-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-https/fetch-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-https/fetch-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-https/fetch-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-https/script-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-https/script-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-https/script-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-https/xhr-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-https/xhr-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/origin/meta-referrer/same-origin/http-https/xhr-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/attr-referrer/cross-origin/http-https/iframe-tag/cross-origin.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/attr-referrer/cross-origin/http-https/iframe-tag/cross-origin.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/attr-referrer/cross-origin/http-https/iframe-tag/cross-origin.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/attr-referrer/cross-origin/http-https/img-tag/cross-origin.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/attr-referrer/cross-origin/http-https/img-tag/cross-origin.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/attr-referrer/cross-origin/http-https/img-tag/cross-origin.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/attr-referrer/same-origin/http-https/iframe-tag/same-origin-insecure.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/attr-referrer/same-origin/http-https/img-tag/same-origin-insecure.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/cross-origin/http-https/fetch-request/cross-origin.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/cross-origin/http-https/fetch-request/cross-origin.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/cross-origin/http-https/fetch-request/cross-origin.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/cross-origin/http-https/iframe-tag/cross-origin.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/cross-origin/http-https/iframe-tag/cross-origin.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/cross-origin/http-https/iframe-tag/cross-origin.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/cross-origin/http-https/img-tag/cross-origin.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/cross-origin/http-https/img-tag/cross-origin.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/cross-origin/http-https/img-tag/cross-origin.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/cross-origin/http-https/script-tag/cross-origin.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/cross-origin/http-https/script-tag/cross-origin.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/cross-origin/http-https/script-tag/cross-origin.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/cross-origin/http-https/xhr-request/cross-origin.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/cross-origin/http-https/xhr-request/cross-origin.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/cross-origin/http-https/xhr-request/cross-origin.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/same-origin/http-https/fetch-request/same-origin-insecure.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/same-origin/http-https/iframe-tag/same-origin-insecure.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/same-origin/http-https/img-tag/same-origin-insecure.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/same-origin/http-https/script-tag/same-origin-insecure.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/http-rp/same-origin/http-https/xhr-request/same-origin-insecure.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/cross-origin/http-https/fetch-request/cross-origin.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/cross-origin/http-https/fetch-request/cross-origin.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/cross-origin/http-https/fetch-request/cross-origin.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/cross-origin/http-https/iframe-tag/cross-origin.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/cross-origin/http-https/iframe-tag/cross-origin.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/cross-origin/http-https/iframe-tag/cross-origin.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/cross-origin/http-https/img-tag/cross-origin.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/cross-origin/http-https/img-tag/cross-origin.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/cross-origin/http-https/img-tag/cross-origin.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/cross-origin/http-https/script-tag/cross-origin.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/cross-origin/http-https/script-tag/cross-origin.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/cross-origin/http-https/script-tag/cross-origin.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/cross-origin/http-https/xhr-request/cross-origin.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/cross-origin/http-https/xhr-request/cross-origin.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/cross-origin/http-https/xhr-request/cross-origin.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/same-origin/http-https/fetch-request/same-origin-insecure.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/same-origin/http-https/iframe-tag/same-origin-insecure.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/same-origin/http-https/img-tag/same-origin-insecure.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/same-origin/http-https/script-tag/same-origin-insecure.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/same-origin/meta-referrer/same-origin/http-https/xhr-request/same-origin-insecure.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/attr-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/attr-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/attr-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/attr-referrer/cross-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/attr-referrer/cross-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/attr-referrer/cross-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/attr-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/attr-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/attr-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/attr-referrer/same-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/attr-referrer/same-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/attr-referrer/same-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/cross-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/cross-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/cross-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/cross-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/cross-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/cross-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/cross-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/cross-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/cross-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/cross-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/cross-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/cross-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/cross-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/cross-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/cross-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/http-rp/same-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/cross-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/cross-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/cross-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/cross-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/cross-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/cross-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/cross-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/cross-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/cross-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin-when-cross-origin/meta-referrer/same-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/attr-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/attr-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/attr-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/attr-referrer/cross-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/attr-referrer/cross-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/attr-referrer/cross-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/attr-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/attr-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/attr-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/attr-referrer/same-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/attr-referrer/same-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/attr-referrer/same-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/cross-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/cross-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/cross-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/cross-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/cross-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/cross-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/cross-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/cross-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/cross-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/cross-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/cross-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/cross-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/cross-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/cross-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/cross-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/http-rp/same-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/cross-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/cross-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/cross-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/cross-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/cross-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/cross-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/cross-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/cross-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/cross-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/strict-origin/meta-referrer/same-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/attr-referrer/cross-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/attr-referrer/cross-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/attr-referrer/cross-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/attr-referrer/cross-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/attr-referrer/cross-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/attr-referrer/cross-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/attr-referrer/same-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/attr-referrer/same-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/attr-referrer/same-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/attr-referrer/same-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/attr-referrer/same-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/attr-referrer/same-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/cross-origin/http-https/fetch-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/cross-origin/http-https/fetch-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/cross-origin/http-https/fetch-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/cross-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/cross-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/cross-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/cross-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/cross-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/cross-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/cross-origin/http-https/script-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/cross-origin/http-https/script-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/cross-origin/http-https/script-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/cross-origin/http-https/xhr-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/cross-origin/http-https/xhr-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/cross-origin/http-https/xhr-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-https/fetch-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-https/fetch-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-https/fetch-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-https/script-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-https/script-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-https/script-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-https/xhr-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-https/xhr-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/http-rp/same-origin/http-https/xhr-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/fetch-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/fetch-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/fetch-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/script-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/script-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/script-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/xhr-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/xhr-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/cross-origin/http-https/xhr-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/fetch-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/fetch-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/fetch-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/iframe-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/iframe-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/iframe-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/img-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/img-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/img-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/script-tag/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/script-tag/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/script-tag/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/xhr-request/generic.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/xhr-request/generic.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unsafe-url/meta-referrer/same-origin/http-https/xhr-request/generic.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/attr-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/attr-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/attr-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/attr-referrer/cross-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/attr-referrer/cross-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/attr-referrer/cross-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/attr-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/attr-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/attr-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/attr-referrer/same-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/attr-referrer/same-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/attr-referrer/same-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/cross-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/cross-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/cross-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/cross-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/cross-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/cross-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/cross-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/cross-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/cross-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/cross-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/cross-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/cross-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/cross-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/cross-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/cross-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/http-rp/same-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/cross-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/fetch-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/fetch-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/fetch-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/iframe-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/img-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/script-tag/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/script-tag/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/script-tag/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/xhr-request/upgrade-protocol.keep-origin-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/xhr-request/upgrade-protocol.no-redirect.http.html [ Failure Timeout ]
-Bug(none) external/wpt/referrer-policy/unset-referrer-policy/meta-referrer/same-origin/http-https/xhr-request/upgrade-protocol.swap-origin-redirect.http.html [ Failure Timeout ]
 Bug(none) external/wpt/resource-timing/resource_TAO_match_origin.htm [ Failure Timeout ]
 Bug(none) external/wpt/resource-timing/resource_TAO_match_wildcard.htm [ Failure Timeout ]
 Bug(none) external/wpt/resource-timing/resource_TAO_multi.htm [ Failure Timeout ]
@@ -1547,67 +422,19 @@
 Bug(none) external/wpt/webmessaging/broadcastchannel/blobs.html [ Failure Timeout ]
 Bug(none) external/wpt/websockets/Secure-Send-binary-blob.htm [ Failure Timeout ]
 Bug(none) external/wpt/websockets/Send-binary-blob.htm [ Failure Timeout ]
-Bug(none) external/wpt/webusb/idlharness.https.html [ Failure Timeout ]
-Bug(none) external/wpt/webusb/usb-allowed-by-feature-policy-attribute-redirect-on-load.https.sub.html [ Timeout ]
-Bug(none) external/wpt/webusb/usb-allowed-by-feature-policy-attribute.https.sub.html [ Failure Timeout ]
-Bug(none) external/wpt/webusb/usb-allowed-by-feature-policy.https.sub.html [ Failure Timeout ]
-Bug(none) external/wpt/webusb/usb-default-feature-policy.https.sub.html [ Failure Timeout ]
-Bug(none) external/wpt/webusb/usb-disabled-by-feature-policy.https.sub.html [ Failure Timeout ]
-Bug(none) external/wpt/webusb/usb-manual.https.html [ Timeout ]
-Bug(none) external/wpt/webusb/usbConnectionEvent.https.html [ Timeout ]
-Bug(none) external/wpt/webusb/usbDevice-iframe.https.html [ Timeout ]
-Bug(none) external/wpt/webusb/usbDevice.https.html [ Timeout ]
-Bug(none) external/wpt/webusb/usbInTransferResult.https.html [ Timeout ]
-Bug(none) external/wpt/webusb/usbIsochronousInTransferPacket.https.html [ Timeout ]
-Bug(none) external/wpt/webusb/usbIsochronousInTransferResult.https.html [ Timeout ]
-Bug(none) external/wpt/webusb/usbIsochronousOutTransferPacket.https.html [ Timeout ]
-Bug(none) external/wpt/webusb/usbIsochronousOutTransferResult.https.html [ Timeout ]
-Bug(none) external/wpt/webusb/usbOutTransferResult.https.html [ Timeout ]
 Bug(none) external/wpt/webvtt/rendering/cues-with-video/processing-model/selectors/cue_function/class_object/class_timestamp_future.html [ Failure Timeout ]
 Bug(none) external/wpt/workers/SharedWorker_blobUrl.html [ Failure Timeout ]
 Bug(none) external/wpt/workers/constructors/Worker/Blob-url.html [ Failure Timeout ]
 Bug(none) external/wpt/workers/name-property.html [ Failure Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-2d-drawImage-in-worker.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-2d-gradients-in-worker.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-2d-imageData-in-worker.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-2d-imageSmoothing-in-worker.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-2d-pattern-in-worker.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-clearRect-in-worker.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-commit-invalid-call.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-constructor-in-worker.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-convertToBlob-noIdleTask-worker.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-convertToBlob-noIdleTask.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-fillRect-in-worker.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-filter-in-worker.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-invalid-args-in-worker.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-multiple-worker-commit.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-paths-in-worker.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-placeholder-image-source-with-worker.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-placeholder-image-source.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-strokeRect-in-worker.html [ Timeout ]
-Bug(none) fast/canvas/OffscreenCanvas-transform-shadow-in-worker.html [ Timeout ]
-Bug(none) fast/canvas/canvas-createImageBitmap-blob-in-workers.html [ Timeout ]
 Bug(none) fast/canvas/canvas-createImageBitmap-drawImage.html [ Crash Failure ]
-Bug(none) fast/canvas/canvas-createImageBitmap-from-canvas-toBlob.html [ Timeout ]
+Bug(none) fast/canvas/webgl/texImage-imageBitmap-from-imageBitmap-from-blob.html [ Crash Failure ]
+Bug(none) fast/canvas/canvas-createImageBitmap-invalid-blob-in-workers.html [ Crash ] 
+Bug(none) fast/canvas/webgl/texImage-imageBitmap-from-blob.html [ Crash Failure ]
+Bug(none) fast/canvas/canvas-createImageBitmap-resize.html [ Crash Failure ]
 Bug(none) fast/canvas/canvas-createImageBitmap-immutable.html [ Crash Timeout ]
 Bug(none) fast/canvas/canvas-createImageBitmap-invalid-args.html [ Crash ]
-Bug(none) fast/canvas/canvas-createImageBitmap-invalid-blob-in-workers.html [ Crash ] 
-Bug(none) fast/canvas/canvas-createImageBitmap-resize.html [ Crash Failure ]
 Bug(none) fast/canvas/canvas-createImageBitmap-size-tooBig.html [ Crash ]
-Bug(none) fast/canvas/canvas-drawImage-live-video.html [ Timeout ]
-Bug(none) fast/canvas/canvas-toBlob-defaultpng.html [ Timeout ]
-Bug(none) fast/canvas/canvas-toBlob-jpeg-maximum-quality.html [ Timeout ]
-Bug(none) fast/canvas/canvas-toBlob-jpeg-medium-quality.html [ Timeout ]
-Bug(none) fast/canvas/canvas-toBlob-toDataURL-race-imageEncoder-jpeg.html [ Timeout ]
-Bug(none) fast/canvas/canvas-toBlob-toDataURL-race-imageEncoder-png.html [ Timeout ]
-Bug(none) fast/canvas/canvas-toBlob-webp-maximum-quality.html [ Timeout ]
-Bug(none) fast/canvas/fillrect-gradient-zero-stops.html [ Timeout ]
-Bug(none) fast/canvas/webgl/offscreenCanvas-context-lost-restored-worker.html [ Timeout ]
-Bug(none) fast/canvas/webgl/offscreenCanvas-context-lost-worker.html [ Timeout ]
-Bug(none) fast/canvas/webgl/offscreenCanvas-transferToImageBitmap-texImage2D.html [ Crash Pass Timeout ]
 Bug(none) fast/canvas/webgl/texImage-imageBitmap-from-blob-resize.html [ Crash Failure ]
-Bug(none) fast/canvas/webgl/texImage-imageBitmap-from-blob.html [ Crash Failure ]
-Bug(none) fast/canvas/webgl/texImage-imageBitmap-from-imageBitmap-from-blob.html [ Crash Failure ]
 Bug(none) fast/css/counters/counter-traverse-table-cell.html [ Failure ]
 Bug(none) fast/css/font-face-attribute-remove.html [ Timeout ]
 Bug(none) fast/css/object-fit-grow-landscape.html [ Failure ]
@@ -1745,31 +572,8 @@
 Bug(none) fast/spatial-navigation/snav-iframe-with-offscreen-focusable-element.html [ Failure ]
 Bug(none) fast/spatial-navigation/snav-media-elements.html [ Timeout ]
 Bug(none) fast/tokenizer/image-empty-crash.html [ Timeout ]
-Bug(none) fast/workers/close-context-messageport-crash.html [ Timeout ]
-Bug(none) fast/workers/dedicated-worker-lifecycle.html [ Timeout ]
 Bug(none) fast/workers/shared-worker-console-log.html [ Timeout ]
-Bug(none) fast/workers/shared-worker-lifecycle.html [ Timeout ]
-Bug(none) fast/workers/shared-worker-name.html [ Timeout ]
-Bug(none) fast/workers/worker-close-more.html [ Timeout ]
-Bug(none) fast/workers/worker-close.html [ Timeout ]
-Bug(none) fast/workers/worker-console-log.html [ Timeout ]
-Bug(none) fast/workers/worker-document-leak.html [ Timeout ]
-Bug(none) fast/workers/worker-exception-during-navigation.html [ Timeout ]
-Bug(none) fast/workers/worker-init.html [ Timeout ]
-Bug(none) fast/workers/worker-messageport-gc.html [ Timeout ]
-Bug(none) fast/workers/worker-multi-startup.html [ Timeout ]
-Bug(none) fast/workers/worker-navigator.html [ Timeout ]
-Bug(none) fast/workers/worker-onerror-01.html [ Failure ]
-Bug(none) fast/workers/worker-onerror-02.html [ Failure ]
-Bug(none) fast/workers/worker-onerror-03.html [ Failure ]
-Bug(none) fast/workers/worker-onerror-04.html [ Timeout ]
-Bug(none) fast/workers/worker-onerror-05.html [ Failure ]
-Bug(none) fast/workers/worker-onerror-06.html [ Failure ]
-Bug(none) fast/workers/worker-onerror-07.html [ Timeout ]
-Bug(none) fast/workers/worker-onerror-08.html [ Failure ]
-Bug(none) fast/workers/worker-onerror-09.html [ Failure ]
-Bug(none) fast/workers/worker-shared-asm-buffer.html [ Timeout ]
-Bug(none) fast/workers/worker-supplement-gc.html [ Timeout ]
+Bug(none) fast/workers/close-context-messageport-crash.html [ Timeout ]
 Bug(none) fast/xmlhttprequest/xmlhttprequest-bad-mimetype.html [ Failure ]
 Bug(none) fast/xmlhttprequest/xmlhttprequest-html-response-encoding.html [ Failure ]
 Bug(none) fast/xmlhttprequest/xmlhttprequest-nonexistent-file.html [ Timeout ]
@@ -1792,49 +596,6 @@
 Bug(none) fullscreen/full-screen-iframe-without-allow-attribute-allowed-from-parent.html [ Failure ]
 Bug(none) fullscreen/video-controls-timeline.html [ Timeout ]
 Bug(none) fullscreen/video-specified-size.html [ Timeout ]
-Bug(none) geolocation-api/cached-position-called-once.html [ Timeout ]
-Bug(none) geolocation-api/callback-exception.html [ Timeout ]
-Bug(none) geolocation-api/callback-to-deleted-context.html [ Timeout ]
-Bug(none) geolocation-api/callback-to-remote-context.html [ Timeout ]
-Bug(none) geolocation-api/callback-to-remote-context2.html [ Timeout ]
-Bug(none) geolocation-api/clear-watch-invalid-id-crash.html [ Timeout ]
-Bug(none) geolocation-api/coordinates-interface-attributes.html [ Timeout ]
-Bug(none) geolocation-api/delayed-permission-allowed-for-multiple-requests.html [ Timeout ]
-Bug(none) geolocation-api/delayed-permission-allowed.html [ Timeout ]
-Bug(none) geolocation-api/delayed-permission-denied-for-multiple-requests.html [ Timeout ]
-Bug(none) geolocation-api/delayed-permission-denied.html [ Timeout ]
-Bug(none) geolocation-api/disconnected-frame-already.html [ Timeout ]
-Bug(none) geolocation-api/disconnected-frame-permission-denied.html [ Timeout ]
-Bug(none) geolocation-api/disconnected-frame.html [ Timeout ]
-Bug(none) geolocation-api/error-clear-watch.html [ Timeout ]
-Bug(none) geolocation-api/error-service-connection-error.html [ Timeout ]
-Bug(none) geolocation-api/error.html [ Timeout ]
-Bug(none) geolocation-api/maximum-age.html [ Timeout ]
-Bug(none) geolocation-api/multiple-requests.html [ Timeout ]
-Bug(none) geolocation-api/notimer-after-unload.html [ Timeout ]
-Bug(none) geolocation-api/permission-denied-already-clear-watch.html [ Timeout ]
-Bug(none) geolocation-api/permission-denied-already-error.html [ Timeout ]
-Bug(none) geolocation-api/permission-denied-already-success.html [ Timeout ]
-Bug(none) geolocation-api/permission-denied-stops-watches.html [ Timeout ]
-Bug(none) geolocation-api/permission-denied.html [ Timeout ]
-Bug(none) geolocation-api/permission-service-connection-error.html [ Timeout ]
-Bug(none) geolocation-api/position-string.html [ Timeout ]
-Bug(none) geolocation-api/reentrant-error.html [ Timeout ]
-Bug(none) geolocation-api/reentrant-permission-denied.html [ Timeout ]
-Bug(none) geolocation-api/reentrant-success.html [ Timeout ]
-Bug(none) geolocation-api/remove-remote-context-in-error-callback-crash.html [ Timeout ]
-Bug(none) geolocation-api/success-clear-watch.html [ Timeout ]
-Bug(none) geolocation-api/success.html [ Timeout ]
-Bug(none) geolocation-api/timeout-clear-watch.html [ Timeout ]
-Bug(none) geolocation-api/timeout-negative.html [ Timeout ]
-Bug(none) geolocation-api/timeout-over-max-of-unsigned.html [ Timeout ]
-Bug(none) geolocation-api/timeout-zero.html [ Timeout ]
-Bug(none) geolocation-api/timeout.html [ Timeout ]
-Bug(none) geolocation-api/timestamp.html [ Timeout ]
-Bug(none) geolocation-api/watch.html [ Timeout ]
-Bug(none) geolocation-api/watchPosition-page-visibility.html [ Timeout ]
-Bug(none) geolocation-api/watchPosition-unique.html [ Timeout ]
-Bug(none) geolocation-api/window-close-crash.html [ Timeout ]
 Bug(none) harness-tests/mojo-helpers.html [ Timeout ]
 Bug(none) html/document_metadata/head-check.html [ Timeout ]
 Bug(none) html/marquee/marquee-clone-crash.html [ Timeout ]
@@ -1860,9 +621,9 @@
 Bug(none) http/tests/appcache/remove-cache.html [ Crash Failure Timeout ]
 Bug(none) http/tests/appcache/simple.html [ Timeout ]
 Bug(none) http/tests/appcache/top-frame-1.html [ Timeout ]
-Bug(none) http/tests/appcache/top-frame-2.html [ Timeout ]
-Bug(none) http/tests/appcache/top-frame-3.html [ Timeout ]
-Bug(none) http/tests/appcache/top-frame-4.html [ Timeout ]
+Bug(none) http/tests/appcache/top-frame-2.html [ Crash Timeout ]
+Bug(none) http/tests/appcache/top-frame-3.html [ Crash Timeout ]
+Bug(none) http/tests/appcache/top-frame-4.html [ Crash Timeout ]
 Bug(none) http/tests/appcache/update-cache.html [ Timeout ]
 Bug(none) http/tests/appcache/video.html [ Failure Timeout ]
 Bug(none) http/tests/appcache/whitelist-wildcard.html [ Failure ]
@@ -2637,50 +1398,6 @@
 Bug(none) imagecapture/setOptions.html [ Timeout ]
 Bug(none) imagecapture/takePhoto-with-PhotoSettings.html [ Timeout ]
 Bug(none) imagecapture/takePhoto.html [ Timeout ]
-Bug(none) images/cHRM_color_spin.html [ Failure ]
-Bug(none) images/color-jpeg-with-color-profile.html [ Failure ]
-Bug(none) images/color-profile-animate-rotate.html [ Failure ]
-Bug(none) images/color-profile-animate.html [ Failure ]
-Bug(none) images/color-profile-background-clip-text.html [ Failure ]
-Bug(none) images/color-profile-background-image-cover.html [ Failure ]
-Bug(none) images/color-profile-background-image-cross-fade-png.html [ Failure ]
-Bug(none) images/color-profile-background-image-cross-fade.html [ Failure ]
-Bug(none) images/color-profile-background-image-repeat.html [ Failure ]
-Bug(none) images/color-profile-background-image-space.html [ Failure ]
-Bug(none) images/color-profile-border-fade.html [ Failure ]
-Bug(none) images/color-profile-border-image.html [ Failure ]
-Bug(none) images/color-profile-border-radius.html [ Failure ]
-Bug(none) images/color-profile-clip.html [ Failure ]
-Bug(none) images/color-profile-drag-image.html [ Failure ]
-Bug(none) images/color-profile-filter.html [ Failure ]
-Bug(none) images/color-profile-group.html [ Failure ]
-Bug(none) images/color-profile-iframe.html [ Failure ]
-Bug(none) images/color-profile-image-canvas-pattern.html [ Failure ]
-Bug(none) images/color-profile-image-canvas-svg.html [ Failure ]
-Bug(none) images/color-profile-image-canvas.html [ Failure ]
-Bug(none) images/color-profile-image-filter-all.html [ Failure ]
-Bug(none) images/color-profile-image-object-fit.html [ Failure ]
-Bug(none) images/color-profile-image-pseudo-content.html [ Failure ]
-Bug(none) images/color-profile-image-shape.html [ Failure ]
-Bug(none) images/color-profile-image-svg-resource-url.html [ Failure ]
-Bug(none) images/color-profile-image.html [ Failure ]
-Bug(none) images/color-profile-layer-filter.html [ Failure ]
-Bug(none) images/color-profile-layer.html [ Failure ]
-Bug(none) images/color-profile-mask-image-svg.html [ Failure ]
-Bug(none) images/color-profile-munsell-adobe-to-srgb.html [ Failure ]
-Bug(none) images/color-profile-object.html [ Failure ]
-Bug(none) images/color-profile-svg-fill-text.html [ Failure ]
-Bug(none) images/color-profile-svg-foreign-object.html [ Failure ]
-Bug(none) images/color-profile-svg.html [ Failure ]
-Bug(none) images/cross-fade-background-size.html [ Failure ]
-Bug(none) images/destroyed-image-load-event.html [ Timeout ]
-Bug(none) images/jpeg-with-color-profile.html [ Failure ]
-Bug(none) images/paletted-png-with-color-profile.html [ Failure ]
-Bug(none) images/png-suite/test.html [ Failure ]
-Bug(none) images/png-with-color-profile.html [ Failure ]
-Bug(none) images/webp-color-profile-lossless.html [ Failure ]
-Bug(none) images/webp-color-profile-lossy-alpha.html [ Failure ]
-Bug(none) images/webp-color-profile-lossy.html [ Failure ]
 Bug(none) inspector-enabled/console/console-uncaught-promise-no-inspector.html [ Timeout ]
 Bug(none) inspector-protocol/accessibility/accessibility-nameSources-buttons.js [ Timeout ]
 Bug(none) inspector-protocol/css/css-get-background-colors.html [ Timeout ]
@@ -3354,7 +2071,6 @@
 Bug(none) webaudio/MediaElementAudioSource/mediaelementaudiosourcenode.html [ Timeout ]
 Bug(none) webaudio/MediaStreamAudioDestination/mediastreamaudiodestinationnode.html [ Timeout ]
 Bug(none) webaudio/MediaStreamAudioSource/mediastreamaudiosourcenode.html [ Timeout ]
-Bug(none) webaudio/OfflineAudioContext/offlineaudiocontext-thread-smoke-test.html [ Timeout ]
 Bug(none) webaudio/Panner/pannernode-basic.html [ Timeout ]
 Bug(none) webaudio/PeriodicWave/periodicwave-lengths.html [ Timeout ]
 Bug(none) webaudio/StereoPanner/stereopannernode-basic.html [ Timeout ]
diff --git a/third_party/WebKit/LayoutTests/TestExpectations b/third_party/WebKit/LayoutTests/TestExpectations
index 36156a8..07ae78c 100644
--- a/third_party/WebKit/LayoutTests/TestExpectations
+++ b/third_party/WebKit/LayoutTests/TestExpectations
@@ -314,7 +314,6 @@
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-bfc-007.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-001l.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-001r.xht [ Failure ]
-crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-top-below-bfc-003r.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-001l.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-001r.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats/floats-wrap-top-below-inline-002l.xht [ Failure ]
@@ -333,9 +332,6 @@
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floating-replaced-height-008.xht [ Skip ]
 crbug.com/719615 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-001.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-005.xht [ Failure ]
-crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-006.xht [ Failure ]
-crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-026.xht [ Failure ]
-crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-027.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-028.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-029.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-036.xht [ Failure ]
@@ -350,23 +346,14 @@
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-131.xht [ Skip ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-132.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-137.xht [ Skip ]
-crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-141.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-143.xht [ Failure ]
-crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-144.xht [ Failure ]
-crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-146.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-018.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-027.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-033.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-034.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-035.xht [ Failure ]
-crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-121.xht [ Failure ]
-crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-122.xht [ Failure ]
-crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-123.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-125.xht [ Failure ]
-crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-134.xht [ Failure ]
-crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-142.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-157.xht [ Failure ]
-crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-158.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-clear-002.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-clear-003.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/margin-collapse-clear-008.xht [ Failure ]
@@ -378,8 +365,15 @@
 # Regressions while changing zero-block-size float behaviour.
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-031.xht [ Failure ]
 crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-114.xht [ Failure ]
-crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-125.xht [ Failure ]
-crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/self-collapsing-block-with-float-descendants.html [ Failure ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/floats-clear/floats-009.xht [ Failure ]
+crbug.com/635619 virtual/layout_ng/external/wpt/css/CSS2/normal-flow/block-in-inline-float-between-001.xht [ Crash ]
+crbug.com/635619 virtual/layout_ng/fast/block/float/float-not-removed-crash.html [ Crash ]
+crbug.com/635619 virtual/layout_ng/fast/block/float/floats-not-cleared-from-grand-parents.html [ Crash ]
+crbug.com/635619 virtual/layout_ng/fast/block/float/intruding-float-not-removed-writing-mode.xhtml [ Crash ]
+crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/001.html [ Failure ]
+crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/005.html [ Failure ]
+crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/block-inside-inline/001.html [ Failure ]
+crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/block-inside-inline/005.html [ Failure ]
 
 ### virtual/layout_ng/external/wpt/css/CSS2/linebox
 
@@ -579,7 +573,6 @@
 crbug.com/635619 virtual/layout_ng/fast/block/float/034.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/035.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/add-float-back-to-anonymous-block.html [ Failure ]
-crbug.com/719615 virtual/layout_ng/fast/block/float/add-inlines-in-block-children-block.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/assert-when-moving-float.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/avoid-floats-when-negative-margin-top-2.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/avoid-floats-when-negative-margin-top-3.html [ Failure ]
@@ -594,7 +587,6 @@
 crbug.com/635619 virtual/layout_ng/fast/block/float/centered-float-avoidance-complexity.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/checkbox-and-radio-avoid-floats.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/clear-intruding-floats-when-moving-to-inline-parent-3.html [ Failure Crash ]
-crbug.com/635619 virtual/layout_ng/fast/block/float/containing-block-change-compositing.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/crash-on-absolute-positioning.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/crash-replaced-display-block.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/editable-text-overlapping-float.html [ Failure ]
@@ -611,13 +603,10 @@
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-not-removed-from-first-letter.html [ Crash ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-not-removed-from-next-sibling-crash.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-not-removed-from-next-sibling5.html [ Failure ]
-crbug.com/635619 virtual/layout_ng/fast/block/float/float-not-removed-from-pre-block.html [ Failure Crash ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-on-empty-line.html [ Failure ]
-crbug.com/635619 virtual/layout_ng/fast/block/float/float-on-line-large-and-small-float-below.html [ Crash ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-on-line-obeys-container-padding.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-on-zero-height-line.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-overflow-hidden-containing-block-width.html [ Failure ]
-crbug.com/635619 virtual/layout_ng/fast/block/float/float-reinsertion-failure.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/float-reparent-during-detach-crash.html [ Crash ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/floats-and-text-indent-rl.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/floats-and-text-indent.html [ Failure ]
@@ -634,13 +623,12 @@
 crbug.com/635619 virtual/layout_ng/fast/block/float/floats-wrap-inside-inline-003.htm [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/floats-wrap-inside-inline-004.htm [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/floats-wrap-inside-inline-007.html [ Failure ]
-crbug.com/635619 virtual/layout_ng/fast/block/float/formatting-context-changes.html [ Failure ]
+crbug.com/635619 virtual/layout_ng/fast/block/float/formatting-context-changes.html [ Failure Crash ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/independent-align-positioning.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/intruding-float-add-in-sibling-block-on-static-position.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/intruding-float-add-in-sibling-block-on-static-position2.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/intruding-painted-twice.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/logical-bottom-exceeds-layoutunit-max.html [ Failure ]
-crbug.com/635619 virtual/layout_ng/fast/block/float/margin-top-changes.html [ Crash ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/marquee-shrink-to-avoid-floats.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/max-width-clear-float-with-overflow-hidden.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/multiple-float-positioning.html [ Failure ]
@@ -651,35 +639,28 @@
 crbug.com/635619 virtual/layout_ng/fast/block/float/nopaint-after-layer-destruction2.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/overhanging-float-add-in-static-position-block.html [ Failure Crash ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/overhanging-float-add-in-static-position-block2.html [ Failure Crash ]
-crbug.com/635619 virtual/layout_ng/fast/block/float/overhanging-float-container-add-compositing.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/overhanging-float-remove-from-fixed-position-block.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/overhanging-float-remove-from-fixed-position-block2.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/overlapping-floats-paint-hittest-order-1.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/overlapping-floats-paint-hittest-order-2.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/override-property-float.html [ Failure ]
-crbug.com/635619 virtual/layout_ng/fast/block/float/relative-painted-twice.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/remove-line-above-float-above-line-crash.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/rubybase-children-made-inline-crash.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/rubybase-children-moved-crash-2.html [ Failure Crash ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/rubybase-children-moved-crash.html [ Crash Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/shrink-to-avoid-float-complexity.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/shrink-to-fit-width.html [ Failure ]
-crbug.com/635619 virtual/layout_ng/fast/block/float/split-inline-sibling-of-float-crash.html [ Crash ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/table-relayout.html [ Failure ]
-crbug.com/635619 virtual/layout_ng/fast/block/float/trailing-float-layout-2.html [ Crash ]
-crbug.com/635619 virtual/layout_ng/fast/block/float/trailing-float-layout.html [ Crash ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/trailing-float-with-columns.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/vertical-move-relayout.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/float/width-update-after-clear.html [ Failure ]
 
 ### virtual/layout_ng/fast/block/margin-collapse
 crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/006.html [ Failure ]
-crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/016.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/025.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/032.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/033.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/043.html [ Failure ]
-crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/044.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/057.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/101.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/103.html [ Failure ]
@@ -695,7 +676,6 @@
 crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/block-inside-inline/011.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/block-inside-inline/012.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/block-inside-inline/015.html [ Failure ]
-crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/block-inside-inline/016.html [ Failure ]
 crbug.com/635619 virtual/layout_ng/fast/block/margin-collapse/block-inside-inline/025.html [ Failure ]
 
 ### virtual/layout_ng/fast/block/margin-collapse
@@ -1897,12 +1877,6 @@
 crbug.com/736050 external/wpt/IndexedDB/upgrade-transaction-lifecycle-backend-aborted.html [ Pass Failure ]
 crbug.com/736050 external/wpt/IndexedDB/value_recursive.htm [ Pass Failure ]
 
-# rebaseline-cl does not handle ref-tests yet...
-crbug.com/736811 fast/css/text-overflow-ellipsis-multiple-shadows.html [ Pass Failure ]
-crbug.com/736811 external/wpt/css/selectors4/focus-within-004.html [ Pass Failure ]
-crbug.com/736811 fast/canvas/canvas-fillPath-gradient-shadow.html [ Pass Failure ]
-crbug.com/736811 virtual/display_list_2d_canvas/fast/canvas/canvas-fillPath-gradient-shadow.html [ Pass Failure ]
-
 # Failures in non-wpt tests from:
 # https://chromium-review.googlesource.com/c/543695/
 # Possibly became flaky after a change in testharness.js.
@@ -1922,6 +1896,11 @@
 crbug.com/626703 virtual/threaded/transitions/transition-end-event-multiple-03.html [ Pass Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_top_navigation-3.html [ Timeout ]
+crbug.com/626703 external/wpt/webrtc/RTCPeerConnection-setLocalDescription-pranswer.html [ Timeout ]
+crbug.com/626703 external/wpt/webrtc/RTCPeerConnection-setLocalDescription-rollback.html [ Timeout ]
+crbug.com/626703 external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-pranswer.html [ Timeout ]
+crbug.com/626703 external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-rollback.html [ Timeout ]
 crbug.com/626703 external/wpt/css/css-tables-3/floats/floats-wrap-bfc-006b.xht [ Failure ]
 crbug.com/626703 external/wpt/css/css-tables-3/floats/floats-wrap-bfc-006c.xht [ Failure ]
 crbug.com/626703 external/wpt/html/webappapis/idle-callbacks/callback-xhr-sync.html [ Timeout ]
@@ -2439,6 +2418,7 @@
 crbug.com/713891 virtual/exotic-color-space/images/animated-png.html [ Pass Failure ]
 
 # [selectors-4]
+crbug.com/706118 external/wpt/css/selectors4/focus-within-004.html [ Failure ]
 crbug.com/706118 external/wpt/css/selectors4/hover-001-manual.html [ Skip ]
 crbug.com/576815 external/wpt/css/selectors4/selectors-dir-selector-ltr-001.html [ Failure ]
 crbug.com/576815 external/wpt/css/selectors4/selectors-dir-selector-rtl-001.html [ Failure ]
@@ -2811,6 +2791,14 @@
 crbug.com/733448 http/tests/inspector/extensions/extensions-network.html [ Failure Pass ]
 crbug.com/733524 [ Mac ] virtual/mojo-loading/http/tests/security/contentSecurityPolicy/report-cross-origin-no-cookies.php [ Timeout Pass ]
 
+# SK_SUPPORT_LEGACY_BILERP_IGNORING_HACK
+crbug.com/740350 external/wpt/css-paint-api/background-image-tiled.html [ Pass Failure ]
+crbug.com/740350 external/wpt/css-paint-api/geometry-background-image-tiled-001.html [ Pass Failure ]
+crbug.com/740350 virtual/android/fast/rootscroller/browser-controls-gradient-background.html [ Pass Failure ]
+crbug.com/740350 virtual/android/fast/rootscroller/browser-controls-gradient-background-iframe-scroller.html [ Pass Failure ]
+crbug.com/740350 fast/forms/calendar-picker/calendar-picker-appearance-zoom125.html [ NeedsManualRebaseline ]
+crbug.com/740350 fast/forms/calendar-picker/calendar-picker-appearance-zoom200.html [ NeedsManualRebaseline ]
+
 # Sheriff failures 2017-06-23
 crbug.com/736548 [ Mac ] css2.1/t040304-c64-uri-00-a-g.html [ Failure Pass ]
 
diff --git a/third_party/WebKit/LayoutTests/VirtualTestSuites b/third_party/WebKit/LayoutTests/VirtualTestSuites
index fece7d4..e25ad070 100644
--- a/third_party/WebKit/LayoutTests/VirtualTestSuites
+++ b/third_party/WebKit/LayoutTests/VirtualTestSuites
@@ -174,8 +174,7 @@
              "--enable-fixed-position-compositing", "--enable-prefer-compositing-to-lcd-text",
              "--enable-composited-scrolling-for-frames", "--enable-gesture-tap-highlight", "--enable-pinch",
              "--force-overlay-fullscreen-video", "--enable-overscroll-notifications",
-             "--enable-fixed-layout", "--enable-viewport", "--disable-canvas-aa",
-             "--disable-composited-antialiasing"]
+             "--enable-viewport", "--disable-canvas-aa", "--disable-composited-antialiasing"]
   },
   {
     "prefix": "android",
@@ -184,8 +183,7 @@
              "--enable-fixed-position-compositing", "--enable-prefer-compositing-to-lcd-text",
              "--enable-composited-scrolling-for-frames", "--enable-gesture-tap-highlight", "--enable-pinch",
              "--force-overlay-fullscreen-video", "--enable-overscroll-notifications",
-             "--enable-fixed-layout", "--enable-viewport", "--disable-canvas-aa",
-             "--disable-composited-antialiasing"]
+             "--enable-viewport", "--disable-canvas-aa", "--disable-composited-antialiasing"]
   },
   {
     "prefix": "media-gpu-accelerated",
diff --git a/third_party/WebKit/LayoutTests/compositing/geometry/horizontal-scroll-composited-expected.png b/third_party/WebKit/LayoutTests/compositing/geometry/horizontal-scroll-composited-expected.png
new file mode 100644
index 0000000..33762fa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/geometry/horizontal-scroll-composited-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/overflow-scroll-with-local-image-background-expected.html b/third_party/WebKit/LayoutTests/compositing/overflow/overflow-scroll-with-local-image-background-expected.html
deleted file mode 100644
index 5e088183..0000000
--- a/third_party/WebKit/LayoutTests/compositing/overflow/overflow-scroll-with-local-image-background-expected.html
+++ /dev/null
@@ -1,24 +0,0 @@
-<script>
-onload = function() {
-    document.getElementById('scroller').scrollTop = 200;
-}
-</script>
-<style>
-#scroller {
-    background: url('../resources/apple.jpg') local;
-    border: 10px solid rgba(0, 255, 0, 0.5);
-    overflow: scroll;
-    padding: 10px;
-    width: 200px;
-    height: 200px;
-}
-
-.spacer {
-    height: 300px;
-}
-</style>
-<!-- This scroller has a locally attached background image which should
-    scroll with the content. -->
-<div id="scroller">
-    <div class="spacer"></div>
-</div>
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/overflow-scroll-with-local-image-background-expected.png b/third_party/WebKit/LayoutTests/compositing/overflow/overflow-scroll-with-local-image-background-expected.png
new file mode 100644
index 0000000..df04d934
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/overflow-scroll-with-local-image-background-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/compositing/overflow/overflow-scroll-with-local-image-background-expected.txt b/third_party/WebKit/LayoutTests/compositing/overflow/overflow-scroll-with-local-image-background-expected.txt
new file mode 100644
index 0000000..becab00
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/compositing/overflow/overflow-scroll-with-local-image-background-expected.txt
@@ -0,0 +1,8 @@
+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 240x240 clip at (18,18) size 205x205 scrollY 115.00 scrollHeight 320
+  LayoutBlockFlow {DIV} at (0,0) size 240x240 [border: (10px solid #00FF0080)]
+    LayoutBlockFlow {DIV} at (20,20) size 185x300
diff --git a/third_party/WebKit/LayoutTests/css3/masking/mask-luminance-gradient-expected.html b/third_party/WebKit/LayoutTests/css3/masking/mask-luminance-gradient-expected.html
deleted file mode 100644
index b16ec5ca..0000000
--- a/third_party/WebKit/LayoutTests/css3/masking/mask-luminance-gradient-expected.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-    <head>
-        <style>
-            #back {
-                width: 800px;
-                height: 400px;
-                background-color: yellow;
-            }
-            #front {
-                width: 600px;
-                height: 200px;
-                background-color: green;
-                border: 50px solid blue;
-                padding: 50px;
-                -webkit-mask-image: linear-gradient(45deg, black, transparent 100%);
-                mask-source-type: alpha;
-                -webkit-mask-size: 200px auto;
-            }
-        </style>
-    </head>
-
-    <body>
-        <div id="back">
-            <div id="front" />
-        </div>
-            </body>
-</html>
-
diff --git a/third_party/WebKit/LayoutTests/css3/masking/mask-luminance-gradient-expected.txt b/third_party/WebKit/LayoutTests/css3/masking/mask-luminance-gradient-expected.txt
new file mode 100644
index 0000000..d83edbb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/css3/masking/mask-luminance-gradient-expected.txt
@@ -0,0 +1,8 @@
+layer at (0,0) size 800x600 clip at (0,0) size 800x585 scrollWidth 808
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x416
+  LayoutBlockFlow {HTML} at (0,0) size 800x416
+    LayoutBlockFlow {BODY} at (8,8) size 784x400
+      LayoutBlockFlow {DIV} at (0,0) size 800x400 [bgcolor=#FFFF00]
+layer at (8,8) size 800x400 backgroundClip at (0,0) size 800x585 clip at (0,0) size 800x585 transparent
+  LayoutBlockFlow {DIV} at (0,0) size 800x400 [bgcolor=#008000] [border: (50px solid #0000FF)]
diff --git a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
index 85a7079e..b03b2ae 100644
--- a/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
+++ b/third_party/WebKit/LayoutTests/external/WPT_BASE_MANIFEST.json
@@ -100964,6 +100964,31 @@
      {}
     ]
    ],
+   "payment-request/allowpaymentrequest/active-document-cross-origin.https.sub-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "payment-request/allowpaymentrequest/active-document-same-origin.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "payment-request/allowpaymentrequest/basic.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "payment-request/allowpaymentrequest/common.sub.js": [
     [
      {}
@@ -100974,21 +100999,46 @@
      {}
     ]
    ],
+   "payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub-expected.txt": [
     [
      {}
     ]
    ],
+   "payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub-expected.txt": [
     [
      {}
     ]
    ],
+   "payment-request/interfaces.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "payment-request/payment-allowed-by-feature-policy.https.sub.html.headers": [
     [
      {}
     ]
    ],
+   "payment-request/payment-default-feature-policy.https.sub-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "payment-request/payment-disabled-by-feature-policy.https.sub.html.headers": [
     [
      {}
@@ -101004,6 +101054,36 @@
      {}
     ]
    ],
+   "payment-request/payment-request-constructor-crash.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "payment-request/payment-request-constructor.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "payment-request/payment-request-id.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "payment-request/payment-request-in-iframe-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "payment-request/payment-request-onshippingaddresschange-attribute.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
+   "payment-request/payment-request-onshippingoptionchange-attribute.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "payment-request/payment-request-response-id.html": [
     [
      {}
@@ -101019,6 +101099,11 @@
      {}
     ]
    ],
+   "payment-request/payment-request-update-event-constructor.https-expected.txt": [
+    [
+     {}
+    ]
+   ],
    "payment-request/payment-request-update-event-updatewith-method.https-expected.txt": [
     [
      {}
@@ -107229,6 +107314,11 @@
      {}
     ]
    ],
+   "webrtc/RTCConfiguration-helper.js": [
+    [
+     {}
+    ]
+   ],
    "webrtc/RTCConfiguration-iceCandidatePoolSize-expected.txt": [
     [
      {}
@@ -107349,6 +107439,11 @@
      {}
     ]
    ],
+   "webrtc/coverage/set-session-description.txt": [
+    [
+     {}
+    ]
+   ],
    "webrtc/datachannel-emptystring-expected.txt": [
     [
      {}
@@ -125577,6 +125672,18 @@
      {}
     ]
    ],
+   "dom/events/Event-timestamp-high-resolution.html": [
+    [
+     "/dom/events/Event-timestamp-high-resolution.html",
+     {}
+    ]
+   ],
+   "dom/events/Event-timestamp-safe-resolution.html": [
+    [
+     "/dom/events/Event-timestamp-safe-resolution.html",
+     {}
+    ]
+   ],
    "dom/events/Event-type-empty.html": [
     [
      "/dom/events/Event-type-empty.html",
@@ -134645,6 +134752,12 @@
      {}
     ]
    ],
+   "html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_top_navigation-3.html": [
+    [
+     "/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_top_navigation-3.html",
+     {}
+    ]
+   ],
    "html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_top_navigation_by_user_activation_without_user_gesture.html": [
     [
      "/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_top_navigation_by_user_activation_without_user_gesture.html",
@@ -164127,6 +164240,12 @@
      {}
     ]
    ],
+   "webrtc/RTCConfiguration-iceTransportPolicy.html": [
+    [
+     "/webrtc/RTCConfiguration-iceTransportPolicy.html",
+     {}
+    ]
+   ],
    "webrtc/RTCDataChannel-bufferedAmount.html": [
     [
      "/webrtc/RTCDataChannel-bufferedAmount.html",
@@ -164259,18 +164378,48 @@
      {}
     ]
    ],
+   "webrtc/RTCPeerConnection-ontrack.html": [
+    [
+     "/webrtc/RTCPeerConnection-ontrack.html",
+     {}
+    ]
+   ],
    "webrtc/RTCPeerConnection-removeTrack.html": [
     [
      "/webrtc/RTCPeerConnection-removeTrack.html",
      {}
     ]
    ],
+   "webrtc/RTCPeerConnection-setLocalDescription-pranswer.html": [
+    [
+     "/webrtc/RTCPeerConnection-setLocalDescription-pranswer.html",
+     {}
+    ]
+   ],
+   "webrtc/RTCPeerConnection-setLocalDescription-rollback.html": [
+    [
+     "/webrtc/RTCPeerConnection-setLocalDescription-rollback.html",
+     {}
+    ]
+   ],
    "webrtc/RTCPeerConnection-setLocalDescription.html": [
     [
      "/webrtc/RTCPeerConnection-setLocalDescription.html",
      {}
     ]
    ],
+   "webrtc/RTCPeerConnection-setRemoteDescription-pranswer.html": [
+    [
+     "/webrtc/RTCPeerConnection-setRemoteDescription-pranswer.html",
+     {}
+    ]
+   ],
+   "webrtc/RTCPeerConnection-setRemoteDescription-rollback.html": [
+    [
+     "/webrtc/RTCPeerConnection-setRemoteDescription-rollback.html",
+     {}
+    ]
+   ],
    "webrtc/RTCPeerConnection-setRemoteDescription.html": [
     [
      "/webrtc/RTCPeerConnection-setRemoteDescription.html",
@@ -164301,6 +164450,12 @@
      {}
     ]
    ],
+   "webrtc/RTCTrackEvent-constructor.html": [
+    [
+     "/webrtc/RTCTrackEvent-constructor.html",
+     {}
+    ]
+   ],
    "webrtc/datachannel-emptystring.html": [
     [
      "/webrtc/datachannel-emptystring.html",
@@ -220266,6 +220421,14 @@
    "5da96a9be09ad5dc69438ba9bd6b2ab58cf77ca1",
    "testharness"
   ],
+  "dom/events/Event-timestamp-high-resolution.html": [
+   "689ee67c1e9a45378cc2fb35384a774515a1d641",
+   "testharness"
+  ],
+  "dom/events/Event-timestamp-safe-resolution.html": [
+   "8e707dcd84b87dc3ebb8cff30e61439ce47bd58a",
+   "testharness"
+  ],
   "dom/events/Event-type-empty.html": [
    "504518675cd65f5f694653f035130509cbf421c7",
    "testharness"
@@ -236278,6 +236441,10 @@
    "9d640f248b376f6bc6a95d09b948e49a3f655954",
    "testharness"
   ],
+  "html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_top_navigation-3.html": [
+   "96453a352d2bed1d208e203594bcb24ab8ee37cd",
+   "testharness"
+  ],
   "html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_top_navigation_by_user_activation-manual.html": [
    "7f8cc0226de24738bc75517e95d2942396b222a8",
    "manual"
@@ -241791,7 +241958,7 @@
    "support"
   ],
   "media-source/interfaces.html": [
-   "6cb50e9726f1ba107b4d4d8e24ca4bfd8599c38f",
+   "fa1b832ea50c89a6fc1880befecc5fa059ceb60a",
    "testharness"
   ],
   "media-source/manifest.txt": [
@@ -250770,22 +250937,42 @@
    "5695dc622d2bc89c33c10fd73aac173c87cc7ad2",
    "testharness"
   ],
+  "payment-request/allowpaymentrequest/active-document-cross-origin.https.sub-expected.txt": [
+   "9ced499a90ef11999bf581780b363aad76ea949f",
+   "support"
+  ],
   "payment-request/allowpaymentrequest/active-document-cross-origin.https.sub.html": [
    "e96ac343e8533e8e90d3cbd4113a902b9e93e0bc",
    "testharness"
   ],
+  "payment-request/allowpaymentrequest/active-document-same-origin.https-expected.txt": [
+   "a19a84a98c286253c2f6048994738241c435f08f",
+   "support"
+  ],
   "payment-request/allowpaymentrequest/active-document-same-origin.https.html": [
    "8bbacc77b15f179bfc7ec4e08809e07181675030",
    "testharness"
   ],
+  "payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https-expected.txt": [
+   "09aa5745fd08b26cca2509b67f2b0d31e5ea9599",
+   "support"
+  ],
   "payment-request/allowpaymentrequest/allowpaymentrequest-attribute-cross-origin-bc-containers.https.html": [
    "844e26e36380dbc9971d21c690a293d62edaa10c",
    "testharness"
   ],
+  "payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https-expected.txt": [
+   "aa2ab91b1d4343a1bee4773c5aaa11de2401c0a5",
+   "support"
+  ],
   "payment-request/allowpaymentrequest/allowpaymentrequest-attribute-same-origin-bc-containers.https.html": [
    "ea6bac2631d7564850853013d8c16a419dc12d7b",
    "testharness"
   ],
+  "payment-request/allowpaymentrequest/basic.https-expected.txt": [
+   "7bae51949f01737bfff3e25f812be047ed201ec3",
+   "support"
+  ],
   "payment-request/allowpaymentrequest/basic.https.html": [
    "0e8a08f2e25a1cc3302d68322f504930ebd3fc8f",
    "testharness"
@@ -250798,28 +250985,40 @@
    "1c0428fd7d3bdc4302bb061f6f99ce98d0e400b2",
    "support"
   ],
+  "payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https-expected.txt": [
+   "68be0a67d754f2dc0e0e21e424dec7516899344b",
+   "support"
+  ],
   "payment-request/allowpaymentrequest/no-attribute-cross-origin-bc-containers.https.html": [
    "fb9049dbf7d5449fc057b5372bedae83d937676a",
    "testharness"
   ],
+  "payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https-expected.txt": [
+   "aa2ab91b1d4343a1bee4773c5aaa11de2401c0a5",
+   "support"
+  ],
   "payment-request/allowpaymentrequest/no-attribute-same-origin-bc-containers.https.html": [
    "2e42808a20c5ebe11720f01cdfab78dd2bf8221a",
    "testharness"
   ],
   "payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub-expected.txt": [
-   "7a03ccde67f470aa9cddc2d51c8e4a2eb9561b37",
+   "cbfaa554af847d0584abe9cad93cc68b4da5c9bf",
    "support"
   ],
   "payment-request/allowpaymentrequest/removing-allowpaymentrequest.https.sub.html": [
    "41265b7c3d0e8d4c8f462f957627139f8aa5a3a3",
    "testharness"
   ],
+  "payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub-expected.txt": [
+   "d335379f8cf4fb70dfc94cf7a71b978772ce85f4",
+   "support"
+  ],
   "payment-request/allowpaymentrequest/setting-allowpaymentrequest-timing.https.sub.html": [
    "5eb37c0c6ad39187c4505a8cbe113c4b68e51c92",
    "testharness"
   ],
   "payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub-expected.txt": [
-   "4454910deefcb86191abb62940d4ee619b48476f",
+   "00c42fa5ada0abe750dd2cfd719fb09eb3e5275e",
    "support"
   ],
   "payment-request/allowpaymentrequest/setting-allowpaymentrequest.https.sub.html": [
@@ -250830,6 +251029,10 @@
    "c0c611a34326ac2eba18e48d640aa358deaae551",
    "testharness"
   ],
+  "payment-request/interfaces.https-expected.txt": [
+   "383ad10aa73720a986fff191e6e639de5fa03b6b",
+   "support"
+  ],
   "payment-request/interfaces.https.html": [
    "8a171d3a4fb4a384b56caa8648f04451a65007fe",
    "testharness"
@@ -250850,6 +251053,10 @@
    "fd48787138bbac80eb51d9f35739f90940a51823",
    "support"
   ],
+  "payment-request/payment-default-feature-policy.https.sub-expected.txt": [
+   "1eeb35079db4704605fba1e8bdf6d315e698c2cb",
+   "support"
+  ],
   "payment-request/payment-default-feature-policy.https.sub.html": [
    "6980a706cca09eaeb2d63d6780a5e0a89ff52fa5",
    "testharness"
@@ -250863,7 +251070,7 @@
    "support"
   ],
   "payment-request/payment-request-abort-method.https-expected.txt": [
-   "a216c871066ec60f37e5df581541972132ae50b0",
+   "c91b92400717606b167367efee1c04718872d346",
    "support"
   ],
   "payment-request/payment-request-abort-method.https.html": [
@@ -250871,33 +251078,57 @@
    "testharness"
   ],
   "payment-request/payment-request-canmakepayment-method.https-expected.txt": [
-   "b03b33a8accbb265df006d5620f853ad118f0776",
+   "884cedd54f968424c937effbbb22c767b8718b41",
    "support"
   ],
   "payment-request/payment-request-canmakepayment-method.https.html": [
    "3b145e1e2164d5201ded51ce138aeeb4163e0261",
    "testharness"
   ],
+  "payment-request/payment-request-constructor-crash.https-expected.txt": [
+   "5523c45757fe8e93cc077f321a7e0b232b538d16",
+   "support"
+  ],
   "payment-request/payment-request-constructor-crash.https.html": [
    "9983391839ed64c41f9a7ecfb48a9b4abe6b497c",
    "testharness"
   ],
+  "payment-request/payment-request-constructor.https-expected.txt": [
+   "cb58692939d93d77a7b5f5f488dd51482ae1505a",
+   "support"
+  ],
   "payment-request/payment-request-constructor.https.html": [
    "786872782a815dcc32c6e93a14e691e4b9541c21",
    "testharness"
   ],
+  "payment-request/payment-request-id.https-expected.txt": [
+   "8ec446f54d3bb82d475dfa4c04add39c439d4ec6",
+   "support"
+  ],
   "payment-request/payment-request-id.https.html": [
    "a90cf1e385cfee1c2090f4144e08b7cb051366d5",
    "testharness"
   ],
+  "payment-request/payment-request-in-iframe-expected.txt": [
+   "40145219ed132de43c4b06a898bdc8568ef079ac",
+   "support"
+  ],
   "payment-request/payment-request-in-iframe.html": [
    "0a7cd9d70a64331eef4277db7e5ee91934b50b11",
    "testharness"
   ],
+  "payment-request/payment-request-onshippingaddresschange-attribute.https-expected.txt": [
+   "e47a64b12833665e0be8cc2962021c90160fb9d6",
+   "support"
+  ],
   "payment-request/payment-request-onshippingaddresschange-attribute.https.html": [
    "c716788baf4b5e74c5bd5adbbd9f95d9ca98ce12",
    "testharness"
   ],
+  "payment-request/payment-request-onshippingoptionchange-attribute.https-expected.txt": [
+   "c6e20c6098347c77c8212aa5c93763e4fc75d58f",
+   "support"
+  ],
   "payment-request/payment-request-onshippingoptionchange-attribute.https.html": [
    "fc4772725ab7cab838d0d7bb97d0febeef8d093c",
    "testharness"
@@ -250922,12 +251153,16 @@
    "6ddbcd3b5847492daf0c2e913369bc861e4d006a",
    "testharness"
   ],
+  "payment-request/payment-request-update-event-constructor.https-expected.txt": [
+   "887c5905a8113a4f0ea5e5dabd0e5069e6867bca",
+   "support"
+  ],
   "payment-request/payment-request-update-event-constructor.https.html": [
    "2a7df6827204f3dd03f5d4a3755f6ed96cdbbb0e",
    "testharness"
   ],
   "payment-request/payment-request-update-event-updatewith-method.https-expected.txt": [
-   "6f7d4ed0c005b4a8af0644148b174c7911531688",
+   "a8fe2fa0ab16af113157b5bdb47d2d47389277c0",
    "support"
   ],
   "payment-request/payment-request-update-event-updatewith-method.https.html": [
@@ -265546,6 +265781,10 @@
    "260ead036b3f4facd720dafbcaaa11040c145228",
    "testharness"
   ],
+  "webrtc/RTCConfiguration-helper.js": [
+   "a3bad314fe0c9d2f6ade069475679e6daa240940",
+   "support"
+  ],
   "webrtc/RTCConfiguration-iceCandidatePoolSize-expected.txt": [
    "a3c6a87b158deb84be0f56e8467b1f9bf16aba71",
    "support"
@@ -265554,6 +265793,10 @@
    "7816790d82628acb7cf04e0a046046884c1207e7",
    "testharness"
   ],
+  "webrtc/RTCConfiguration-iceTransportPolicy.html": [
+   "f95cceffe7485aac7b53d3f891ad87d50ccc8b1d",
+   "testharness"
+  ],
   "webrtc/RTCDataChannel-bufferedAmount.html": [
    "49f27767835ae80163b2a2889e6d5e98def5e22a",
    "testharness"
@@ -265595,7 +265838,7 @@
    "support"
   ],
   "webrtc/RTCPeerConnection-addTrack.html": [
-   "841320f0521a34d84ebd4dd8375e641a0d693c15",
+   "c434d2cdcb134f28b203df07cecca04e11195700",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-addTransceiver-expected.txt": [
@@ -265603,7 +265846,7 @@
    "support"
   ],
   "webrtc/RTCPeerConnection-addTransceiver.html": [
-   "b4721c2afe4e50a9dc2c01a8f9f786029f6f81d2",
+   "62d6e1c76f9a05f7571a5b00ccbe8c3baf0b7786",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-canTrickleIceCandidates-expected.txt": [
@@ -265627,7 +265870,7 @@
    "support"
   ],
   "webrtc/RTCPeerConnection-constructor.html": [
-   "785610c964c8ed95a3b4f65c68a2612c2442145a",
+   "d76f9d46977d91e7dda96729b0dc4ad41f95b670",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-createAnswer-expected.txt": [
@@ -265643,7 +265886,7 @@
    "support"
   ],
   "webrtc/RTCPeerConnection-createDataChannel.html": [
-   "47e58b26cf295fa1a0559ac7de7d1f119cb05106",
+   "0e2c9ab2b4900aa7955d75f867bb5958c7c70ce3",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-createOffer.html": [
@@ -265707,7 +265950,11 @@
    "testharness"
   ],
   "webrtc/RTCPeerConnection-onnegotiationneeded.html": [
-   "e74e16479aca577be6673056eef0fd0212ec7151",
+   "f54dc1857f0323eded11c04aa5d91edc997d2a8f",
+   "testharness"
+  ],
+  "webrtc/RTCPeerConnection-ontrack.html": [
+   "50a4c96761365cba89d6f7646869d0eb067f1dbc",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-removeTrack-expected.txt": [
@@ -265715,19 +265962,35 @@
    "support"
   ],
   "webrtc/RTCPeerConnection-removeTrack.html": [
-   "6e0b10df88f69f33ff9aac63975cfea2561f28a0",
+   "561575bea206ec1c9572e1e5e6f97d1e0bebe2d1",
+   "testharness"
+  ],
+  "webrtc/RTCPeerConnection-setLocalDescription-pranswer.html": [
+   "403b01796ca156e3a3157fbc0a64929348749a6e",
+   "testharness"
+  ],
+  "webrtc/RTCPeerConnection-setLocalDescription-rollback.html": [
+   "e1aea45480a7c486d8396c96654da986efbbe6f9",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-setLocalDescription.html": [
-   "3a182c851b4724e34e0baaacb9f0670e741c0e49",
+   "d8496a8c16ea0526ba4000cc288bb895cbfcf73d",
    "testharness"
   ],
   "webrtc/RTCPeerConnection-setRemoteDescription-expected.txt": [
    "e48c21dca1fce4f9959bdde0bd302112146088ff",
    "support"
   ],
+  "webrtc/RTCPeerConnection-setRemoteDescription-pranswer.html": [
+   "35b884aa8bdbebbe646ae27ebedf5ae722790d48",
+   "testharness"
+  ],
+  "webrtc/RTCPeerConnection-setRemoteDescription-rollback.html": [
+   "7aace4060f519c96d9cba3f27e48dee7af916c51",
+   "testharness"
+  ],
   "webrtc/RTCPeerConnection-setRemoteDescription.html": [
-   "b3e0010a4e7a17a881c4d4a2dfc010cfad98a79a",
+   "acb988b27f0aeadb04b582c3facdd1ea80548dd0",
    "testharness"
   ],
   "webrtc/RTCPeerConnectionIceEvent-constructor-expected.txt": [
@@ -265759,9 +266022,17 @@
    "support"
   ],
   "webrtc/RTCSctpTransport-constructor.html": [
-   "3b975dbe89ea36a78df48510bf1db5d06628db0f",
+   "311250883925fc2d94e2716f4eddcdb46ed9da57",
    "testharness"
   ],
+  "webrtc/RTCTrackEvent-constructor.html": [
+   "4b9e3d6e2498b56cd027bbb6ccf25d05dcdc4a39",
+   "testharness"
+  ],
+  "webrtc/coverage/set-session-description.txt": [
+   "a356e9bb1d8919d87d42c44b2281a4cc648380b2",
+   "support"
+  ],
   "webrtc/datachannel-emptystring-expected.txt": [
    "fe26a16716e99fd3ff9fef057a6de46b3439d1bf",
    "support"
diff --git a/third_party/WebKit/LayoutTests/external/wpt/2dcontext/imagebitmap/createImageBitmap-sizeOverflow.html b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/imagebitmap/createImageBitmap-sizeOverflow.html
new file mode 100644
index 0000000..f58825cc3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/2dcontext/imagebitmap/createImageBitmap-sizeOverflow.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<title>createImageBitmap with size overflow</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+promise_test(function() {
+    var imgData = new ImageData(20, 20);
+    return new Promise(function(resolve, reject) {
+        createImageBitmap(imgData, 4294967400, 10, 10, 10).then(resolve, reject);
+    });
+}, "createImageBitmap does not crash or reject the promise when passing very large sx");
+
+promise_test(function() {
+    var imgData = new ImageData(20, 20);
+    return new Promise(function(resolve, reject) {
+        createImageBitmap(imgData, 10, 4294967400, 10, 10).then(resolve, reject);
+    });
+}, "createImageBitmap does not crash or reject the promise when passing very large sy");
+
+promise_test(function() {
+    var imgData = new ImageData(20, 20);
+    return new Promise(function(resolve, reject) {
+        createImageBitmap(imgData, 10, 10, 4294967400, 10).then(resolve, reject);
+    });
+}, "createImageBitmap does not crash or reject the promise when passing very large sw");
+
+promise_test(function() {
+    var imgData = new ImageData(20, 20);
+    return new Promise(function(resolve, reject) {
+        createImageBitmap(imgData, 10, 10, 10, 4294967400).then(resolve, reject);
+    });
+}, "createImageBitmap does not crash or reject the promise when passing very large sh");
+
+promise_test(function() {
+    var imgData = new ImageData(20, 20);
+    return new Promise(function(resolve, reject) {
+        createImageBitmap(imgData, 4294967400, 4294967400, 4294967400, 4294967400).then(resolve, reject);
+    });
+}, "createImageBitmap does not crash or reject the promise when passing very large sx, sy, sw and sh");
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_top_navigation-3.html b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_top_navigation-3.html
new file mode 100644
index 0000000..9de5d53
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_top_navigation-3.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <meta charset="utf-8">
+    <title>Check that sandboxed iframe can perform navigation on the top frame
+           when allow-top-navigation is set (even when
+           allow-top-navigation-by-user-activation is set)</title>
+    <script src="/resources/testharness.js"></script>
+    <script src="/resources/testharnessreport.js"></script>
+  </head>
+  <body>
+    <!-- Specifying both allow-top-navigation and
+         allow-top-navigation-by-user-activation is a document conformance
+         error: allow-top-navigation-by-user-activation will have no effect. -->
+    <iframe sandbox="allow-top-navigation allow-top-navigation-by-user-activation allow-scripts"></iframe>
+    <script>
+      if (opener) {
+        // We're the popup (i.e. a top frame).  Load into the iframe the page
+        // trying to modifying the top frame and transmit the result to our
+        // opener.
+        onmessage = function(e) {
+          opener.postMessage(e.data, "*")
+        }
+        document.querySelector("iframe").src = "support/iframe-that-performs-top-navigation-on-popup.html";
+      } else {
+        // We are the main test page.  Open ourselves as a popup, so that we can
+        // can experiment navigation of the top frame.
+        async_test(t => {
+          window.addEventListener("message", t.step_func_done(e => {
+            assert_equals(e.data, "can navigate");
+            e.source.close();
+          }));
+          window.open(location.href);
+        }, "Frames with `allow-top-navigation` should be able to navigate the top frame even when `allow-top-navigation-by-user-activation` is set.");
+      }
+    </script>
+  </body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/media-source/interfaces.html b/third_party/WebKit/LayoutTests/external/wpt/media-source/interfaces.html
index f7f6d7c..a01a161 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/media-source/interfaces.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/media-source/interfaces.html
@@ -129,7 +129,7 @@
 video.src = URL.createObjectURL(mediaSource);
 mediaSource.addEventListener("sourceopen", function () {
   var defaultType ='video/webm;codecs="vp8,vorbis"';
-  if (video.canPlayType(defaultType)) {
+  if (MediaSource.isTypeSupported(defaultType)) {
     sourceBuffer = mediaSource.addSourceBuffer(defaultType);
   } else {
     sourceBuffer = mediaSource.addSourceBuffer('video/mp4');
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/idlharness.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/web-share/idlharness.https-expected.txt
deleted file mode 100644
index 95f8804d..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/web-share/idlharness.https-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-This is a testharness.js-based test.
-PASS Test driver 
-FAIL Navigator interface: operation share(ShareData) assert_equals: property has wrong .length expected 0 but got 1
-PASS Navigator interface: navigator must inherit property "share" with the proper type (0) 
-PASS Navigator interface: calling share(ShareData) on navigator with too few arguments must throw TypeError 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-empty.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-empty.https-expected.txt
deleted file mode 100644
index cad8a4d..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-empty.https-expected.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a testharness.js-based test.
-PASS share with no arguments (same as empty dictionary) 
-FAIL share with an empty dictionary assert_throws: function "function () { throw e }" threw object "SecurityError: Must be handling a user gesture to perform a share request." ("SecurityError") expected object "TypeError" ("TypeError")
-FAIL share with a undefined argument (same as empty dictionary) assert_throws: function "function () { throw e }" threw object "SecurityError: Must be handling a user gesture to perform a share request." ("SecurityError") expected object "TypeError" ("TypeError")
-FAIL share with a null argument (same as empty dictionary) assert_throws: function "function () { throw e }" threw object "SecurityError: Must be handling a user gesture to perform a share request." ("SecurityError") expected object "TypeError" ("TypeError")
-FAIL share with a dictionary containing only surplus fields assert_throws: function "function () { throw e }" threw object "SecurityError: Must be handling a user gesture to perform a share request." ("SecurityError") expected object "TypeError" ("TypeError")
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-without-user-gesture.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/web-share/share-without-user-gesture.https-expected.txt
deleted file mode 100644
index c230bd5..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/web-share/share-without-user-gesture.https-expected.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-This is a testharness.js-based test.
-FAIL share without a user gesture assert_throws: function "function () { throw e }" threw object "SecurityError: Must be handling a user gesture to perform a share request." that is not a DOMException NotAllowedError: property "code" is equal to 18, expected 0
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCConfiguration-helper.js b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCConfiguration-helper.js
new file mode 100644
index 0000000..655768b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCConfiguration-helper.js
@@ -0,0 +1,24 @@
+'use strict';
+
+// Run a test function as two test cases.
+// The first test case test the configuration by passing a given config
+// to the constructor.
+// The second test case create an RTCPeerConnection object with default
+// configuration, then call setConfiguration with the provided config.
+// The test function is given a constructor function to create
+// a new instance of RTCPeerConnection with given config,
+// either directly as constructor parameter or through setConfiguration.
+function config_test(test_func, desc) {
+  test(() => {
+    test_func(config => new RTCPeerConnection(config));
+  }, `new RTCPeerConnection(config) - ${desc}`);
+
+  test(() => {
+    test_func(config => {
+      const pc = new RTCPeerConnection();
+      assert_own_property(pc, 'setConfiguration');
+      pc.setConfiguration(config);
+      return pc;
+    })
+  }, `setConfiguration(config) - ${desc}`);
+}
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCConfiguration-iceTransportPolicy-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCConfiguration-iceTransportPolicy-expected.txt
new file mode 100644
index 0000000..8121b20
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCConfiguration-iceTransportPolicy-expected.txt
@@ -0,0 +1,19 @@
+This is a testharness.js-based test.
+FAIL new RTCPeerConnection() should have default iceTransportPolicy all pc.getConfiguration is not a function
+FAIL new RTCPeerConnection({ iceTransportPolicy: undefined }) should have default iceTransportPolicy all pc.getConfiguration is not a function
+FAIL new RTCPeerConnection({ iceTransportPolicy: 'all' }) should succeed pc.getConfiguration is not a function
+FAIL new RTCPeerConnection({ iceTransportPolicy: 'relay' }) should succeed pc.getConfiguration is not a function
+FAIL setConfiguration({ iceTransportPolicy: 'relay' }) with initial iceTransportPolicy all should succeed pc.getConfiguration is not a function
+FAIL setConfiguration({ iceTransportPolicy: 'all' }) with initial iceTransportPolicy relay should succeed pc.getConfiguration is not a function
+FAIL setConfiguration({}) with initial iceTransportPolicy relay should set new value to all pc.getConfiguration is not a function
+PASS new RTCPeerConnection(config) - with invalid iceTransportPolicy should throw TypeError 
+FAIL setConfiguration(config) - with invalid iceTransportPolicy should throw TypeError assert_own_property: expected property "setConfiguration" missing
+PASS new RTCPeerConnection(config) - with none iceTransportPolicy should throw TypeError 
+FAIL setConfiguration(config) - with none iceTransportPolicy should throw TypeError assert_own_property: expected property "setConfiguration" missing
+PASS new RTCPeerConnection(config) - with null iceTransportPolicy should throw TypeError 
+FAIL setConfiguration(config) - with null iceTransportPolicy should throw TypeError assert_own_property: expected property "setConfiguration" missing
+FAIL new RTCPeerConnection({ iceTransports: 'relay' }) should have no effect pc.getConfiguration is not a function
+FAIL new RTCPeerConnection({ iceTransports: 'invalid' }) should have no effect Failed to construct 'RTCPeerConnection': The provided value 'invalid' is not a valid enum value of type RTCIceTransportPolicy.
+FAIL new RTCPeerConnection({ iceTransports: null }) should have no effect Failed to construct 'RTCPeerConnection': The provided value 'null' is not a valid enum value of type RTCIceTransportPolicy.
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCConfiguration-iceTransportPolicy.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCConfiguration-iceTransportPolicy.html
new file mode 100644
index 0000000..7387c54
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCConfiguration-iceTransportPolicy.html
@@ -0,0 +1,119 @@
+<!doctype html>
+<title>RTCConfiguration iceTransportPolicy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="RTCConfiguration-helper.js"></script>
+<script>
+  'use strict';
+
+  // Test is based on the following editor draft:
+  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
+
+  // The following helper function is called from RTCConfiguration-helper.js:
+  //   config_test
+
+  /*
+    [Constructor(optional RTCConfiguration configuration)]
+    interface RTCPeerConnection : EventTarget {
+      RTCConfiguration                   getConfiguration();
+      void                               setConfiguration(RTCConfiguration configuration);
+      ...
+    };
+
+    dictionary RTCConfiguration {
+      sequence<RTCIceServer>   iceServers;
+      RTCIceTransportPolicy    iceTransportPolicy = "all";
+    };
+
+    enum RTCIceTransportPolicy {
+      "relay",
+      "all"
+    };
+   */
+
+  test(() => {
+    const pc = new RTCPeerConnection();
+    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
+  }, `new RTCPeerConnection() should have default iceTransportPolicy all`);
+
+  test(() => {
+    const pc = new RTCPeerConnection({ iceTransportPolicy: undefined });
+    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
+  }, `new RTCPeerConnection({ iceTransportPolicy: undefined }) should have default iceTransportPolicy all`);
+
+  test(() => {
+    const pc = new RTCPeerConnection({ iceTransportPolicy: 'all' });
+    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
+  }, `new RTCPeerConnection({ iceTransportPolicy: 'all' }) should succeed`);
+
+  test(() => {
+    const pc = new RTCPeerConnection({ iceTransportPolicy: 'relay' });
+    assert_equals(pc.getConfiguration().iceTransportPolicy, 'relay');
+  }, `new RTCPeerConnection({ iceTransportPolicy: 'relay' }) should succeed`);
+
+  /*
+    4.3.2. Set a configuration
+      8.  Set the ICE Agent's ICE transports setting to the value of
+          configuration.iceTransportPolicy. As defined in [JSEP] (section 4.1.16.),
+          if the new ICE transports setting changes the existing setting, no action
+          will be taken until the next gathering phase. If a script wants this to
+          happen immediately, it should do an ICE restart.
+   */
+  test(() => {
+    const pc = new RTCPeerConnection({ iceTransportPolicy: 'all' });
+    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
+
+    pc.setConfiguration({ iceTransportPolicy: 'relay' });
+    assert_equals(pc.getConfiguration(), iceTransportPolicy, 'relay');
+  }, `setConfiguration({ iceTransportPolicy: 'relay' }) with initial iceTransportPolicy all should succeed`);
+
+  test(() => {
+    const pc = new RTCPeerConnection({ iceTransportPolicy: 'relay' });
+    assert_equals(pc.getConfiguration().iceTransportPolicy, 'relay');
+
+    pc.setConfiguration({ iceTransportPolicy: 'all' });
+    assert_equals(pc.getConfiguration(), iceTransportPolicy, 'all');
+  }, `setConfiguration({ iceTransportPolicy: 'all' }) with initial iceTransportPolicy relay should succeed`);
+
+  test(() => {
+    const pc = new RTCPeerConnection({ iceTransportPolicy: 'relay' });
+    assert_equals(pc.getConfiguration().iceTransportPolicy, 'relay');
+
+    // default value for iceTransportPolicy is all
+    pc.setConfiguration({});
+    assert_equals(pc.getConfiguration(), iceTransportPolicy, 'all');
+  }, `setConfiguration({}) with initial iceTransportPolicy relay should set new value to all`);
+
+  config_test(makePc => {
+    assert_throws(new TypeError(), () =>
+      makePc({ iceTransportPolicy: 'invalid' }));
+  }, `with invalid iceTransportPolicy should throw TypeError`);
+
+  // "none" is in Blink and Gecko's IDL, but not in the spec.
+  config_test(makePc => {
+    assert_throws(new TypeError(), () =>
+      makePc({ iceTransportPolicy: 'none' }));
+  }, `with none iceTransportPolicy should throw TypeError`);
+
+  config_test(makePc => {
+    assert_throws(new TypeError(), () =>
+      makePc({ iceTransportPolicy: null }));
+  }, `with null iceTransportPolicy should throw TypeError`);
+
+  // iceTransportPolicy is called iceTransports in Blink.
+  test(() => {
+    const pc = new RTCPeerConnection({ iceTransports: 'relay' });
+    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
+  }, `new RTCPeerConnection({ iceTransports: 'relay' }) should have no effect`);
+
+  test(() => {
+    const pc = new RTCPeerConnection({ iceTransports: 'invalid' });
+    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
+  }, `new RTCPeerConnection({ iceTransports: 'invalid' }) should have no effect`);
+
+  test(() => {
+    const pc = new RTCPeerConnection({ iceTransports: null });
+    assert_equals(pc.getConfiguration().iceTransportPolicy, 'all');
+  }, `new RTCPeerConnection({ iceTransports: null }) should have no effect`);
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack-expected.txt
index 8f983ad5..96fc9fc 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack-expected.txt
@@ -1,9 +1,11 @@
 This is a testharness.js-based test.
-FAIL addTrack when pc is closed should throw InvalidStateError assert_own_property: expected property "addTrack" missing
-FAIL addTrack with single track argument should succeed assert_own_property: expected property "addTrack" missing
-FAIL Adding the same track multiple times should throw InvalidAccessError assert_own_property: expected property "addTrack" missing
-FAIL addTrack with existing sender with null track, same kind, and recvonly direction should reuse sender assert_own_property: expected property "addTrack" missing
-FAIL addTrack with existing sender with null track, same kind, and sendrecv direction should create new sender assert_own_property: expected property "addTrack" missing
-FAIL addTrack with existing sender with null track, different kind, and recvonly direction should create new sender assert_own_property: expected property "addTrack" missing
+FAIL addTrack when pc is closed should throw InvalidStateError promise_test: Unhandled rejection with value: object "NotSupportedError: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV)."
+FAIL addTrack with single track argument and no mediaStream should succeed promise_test: Unhandled rejection with value: object "NotSupportedError: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV)."
+FAIL addTrack with single track argument and single mediaStream should succeed promise_test: Unhandled rejection with value: object "NotSupportedError: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV)."
+FAIL addTrack with single track argument and multiple mediaStreams should succeed promise_test: Unhandled rejection with value: object "NotSupportedError: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV)."
+FAIL Adding the same track multiple times should throw InvalidAccessError promise_test: Unhandled rejection with value: object "NotSupportedError: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV)."
+FAIL addTrack with existing sender with null track, same kind, and recvonly direction should reuse sender pc.addTransceiver is not a function
+FAIL addTrack with existing sender with null track, same kind, and sendrecv direction should create new sender pc.addTransceiver is not a function
+FAIL addTrack with existing sender with null track, different kind, and recvonly direction should create new sender pc.addTransceiver is not a function
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack.html
index 9b74b76..406e2d7c 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTrack.html
@@ -37,13 +37,20 @@
     5.1.  addTrack
       4.  If connection's [[isClosed]] slot is true, throw an InvalidStateError.
    */
-  test(t => {
+  promise_test(t => {
     const pc = new RTCPeerConnection();
-    assert_own_property(pc, 'addTrack');
 
-    const track = generateMediaStreamTrack('audio');
-    pc.close();
-    assert_throws('InvalidStateError', () => pc.addTrack(track))
+    return navigator.mediaDevices.getUserMedia({ audio: true })
+    .then(mediaStream => {
+      const tracks = mediaStream.getTracks();
+      assert_greater_than(tracks.length, 0,
+        'Expect getUserMedia to return at least one audio track');
+
+      const track = tracks[0];
+
+      pc.close();
+      assert_throws('InvalidStateError', () => pc.addTrack(track, mediaStream))
+    });
   }, 'addTrack when pc is closed should throw InvalidStateError');
 
   /*
@@ -57,35 +64,81 @@
               transceiver be the result.
           4.  Add transceiver to connection's set of transceivers.
    */
-  test(t => {
+  promise_test(t => {
     const pc = new RTCPeerConnection();
-    assert_own_property(pc, 'addTrack');
 
-    const track = generateMediaStreamTrack('audio');
-    const sender = pc.addTrack(track);
+    return navigator.mediaDevices.getUserMedia({ audio: true })
+    .then(mediaStream => {
+      const tracks = mediaStream.getTracks();
+      assert_greater_than(tracks.length, 0,
+        'Expect getUserMedia to return at least one audio track');
 
-    assert_true(sender instanceof RTCRtpSender,
-      'Expect sender to be instance of RTCRtpSender');
+      const track = tracks[0];
+      const sender = pc.addTrack(track);
 
-    assert_equals(sender.track, track,
-      `Expect sender's track to be the added track`);
+      assert_true(sender instanceof RTCRtpSender,
+        'Expect sender to be instance of RTCRtpSender');
 
-    const transceivers = pc.getTransceivers();
-    assert_equals(transceivers.length, 1,
-      'Expect only one transceiver with sender added');
+      assert_equals(sender.track, track,
+        `Expect sender's track to be the added track`);
 
-    const [transceiver] = transceivers;
-    assert_equals(transceiver.sender, sender);
+      const transceivers = pc.getTransceivers();
+      assert_equals(transceivers.length, 1,
+        'Expect only one transceiver with sender added');
 
-    assert_array_equals([sender], pc.getSenders(),
-      'Expect only one sender with given track added');
+      const [transceiver] = transceivers;
+      assert_equals(transceiver.sender, sender);
 
-    const { receiver } = transceiver;
-    assert_equals(receiver.track.kind, 'audio');
-    assert_array_equals([transceiver.receiver], pc.getReceivers(),
-      'Expect only one receiver associated with transceiver added');
+      assert_array_equals([sender], pc.getSenders(),
+        'Expect only one sender with given track added');
 
-  }, 'addTrack with single track argument should succeed');
+      const { receiver } = transceiver;
+      assert_equals(receiver.track.kind, 'audio');
+      assert_array_equals([transceiver.receiver], pc.getReceivers(),
+        'Expect only one receiver associated with transceiver added');
+    });
+  }, 'addTrack with single track argument and no mediaStream should succeed');
+
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+
+    return navigator.mediaDevices.getUserMedia({ audio: true })
+    .then(mediaStream => {
+      const tracks = mediaStream.getTracks();
+      assert_greater_than(tracks.length, 0,
+        'Expect getUserMedia to return at least one audio track');
+
+      const track = tracks[0];
+      const sender = pc.addTrack(track, mediaStream);
+
+      assert_true(sender instanceof RTCRtpSender,
+        'Expect sender to be instance of RTCRtpSender');
+
+      assert_equals(sender.track, track,
+        `Expect sender's track to be the added track`);
+    });
+  }, 'addTrack with single track argument and single mediaStream should succeed');
+
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+
+    return navigator.mediaDevices.getUserMedia({ audio: true })
+    .then(mediaStream => {
+      const tracks = mediaStream.getTracks();
+      assert_greater_than(tracks.length, 0,
+        'Expect getUserMedia to return at least one audio track');
+
+      const track = tracks[0];
+      const mediaStream2 = new MediaStream([track]);
+      const sender = pc.addTrack(track, mediaStream, mediaStream2);
+
+      assert_true(sender instanceof RTCRtpSender,
+        'Expect sender to be instance of RTCRtpSender');
+
+      assert_equals(sender.track, track,
+        `Expect sender's track to be the added track`);
+    });
+  }, 'addTrack with single track argument and multiple mediaStreams should succeed');
 
   /*
     5.1.  addTrack
@@ -93,15 +146,20 @@
           If an RTCRtpSender for track already exists in senders, throw an
           InvalidAccessError.
    */
-  test(t => {
+  promise_test(t => {
     const pc = new RTCPeerConnection();
-    assert_own_property(pc, 'addTrack');
 
-    const track = generateMediaStreamTrack('audio');
-    pc.addTrack(track);
+    return navigator.mediaDevices.getUserMedia({ audio: true })
+    .then(mediaStream => {
+      const tracks = mediaStream.getTracks();
+      assert_greater_than(tracks.length, 0,
+        'Expect getUserMedia to return at least one audio track');
 
-    assert_throws('InvalidAccessError', () => pc.addTrack(track));
+      const track = tracks[0];
 
+      pc.addTrack(track, mediaStream);
+      assert_throws('InvalidAccessError', () => pc.addTrack(track, mediaStream));
+    });
   }, 'Adding the same track multiple times should throw InvalidAccessError');
 
   /*
@@ -124,7 +182,6 @@
    */
   test(t => {
     const pc = new RTCPeerConnection();
-    assert_own_property(pc, 'addTrack');
 
     const transceiver = pc.addTransceiver('audio', { direction: 'recvonly' });
     assert_equals(transceiver.sender.track, null);
@@ -142,8 +199,6 @@
 
   test(t => {
     const pc = new RTCPeerConnection();
-    assert_own_property(pc, 'addTrack');
-    assert_own_property(pc, 'addTransceiver');
 
     const transceiver = pc.addTransceiver('audio');
     assert_equals(transceiver.sender.track, null);
@@ -169,8 +224,6 @@
 
   test(t => {
     const pc = new RTCPeerConnection();
-    assert_own_property(pc, 'addTrack');
-    assert_own_property(pc, 'addTransceiver');
 
     const transceiver = pc.addTransceiver('video', { direction: 'recvonly' });
     assert_equals(transceiver.sender.track, null);
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver-expected.txt
index d278bd4..146f8b8 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver-expected.txt
@@ -1,7 +1,10 @@
 This is a testharness.js-based test.
+FAIL addTransceiver() with string argument as invalid kind should throw TypeError assert_own_property: expected property "addTransceiver" missing
 FAIL addTransceiver('audio') should return an audio transceiver assert_own_property: expected property "addTransceiver" missing
 FAIL addTransceiver('video') should return a video transceiver assert_own_property: expected property "addTransceiver" missing
-FAIL addTransceiver() with string argument as invalid kind should throw TypeError assert_own_property: expected property "addTransceiver" missing
+FAIL addTransceiver() with direction sendonly should have result transceiver.direction be the same pc.addTransceiver is not a function
+FAIL addTransceiver() with direction inactive should have result transceiver.direction be the same pc.addTransceiver is not a function
+FAIL addTransceiver() with invalid direction should throw TypeError assert_own_property: expected property "addTransceiver" missing
 FAIL addTransceiver(track) should have result with sender.track be given track assert_own_property: Expect pc to have addTransceiver() method expected property "addTransceiver" missing
 FAIL addTransceiver(track) multiple times should create multiple transceivers assert_own_property: Expect pc to have addTransceiver() method expected property "addTransceiver" missing
 Harness: the test ran to completion.
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver.html
index 1336fea9..cc994fc8 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-addTransceiver.html
@@ -8,27 +8,63 @@
   'use strict';
 
   // Test is based on the following editor draft:
-  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
+  // https://rawgit.com/w3c/webrtc-pc/cc8d80f455b86c8041d63bceb8b457f45c72aa89/webrtc.html
 
-  // The following helper function is called from RTCPeerConnection-helper.js:
-  // generateMediaStreamTrack
+  // The following helper functions are called from RTCPeerConnection-helper.js:
+  //   generateMediaStreamTrack()
 
   /*
-   *  5.1. RTCPeerConnection Interface Extensions
-   *  partial interface RTCPeerConnection {
-   *      sequence<RTCRtpSender>      getSenders();
-   *      sequence<RTCRtpReceiver>    getReceivers();
-   *      sequence<RTCRtpTransceiver> getTransceivers();
-   *      RTCRtpTransceiver           addTransceiver((MediaStreamTrack or DOMString) trackOrKind,
-   *                                                 optional RTCRtpTransceiverInit init);
-   *      ...
-   *  };
-   *
-   *  dictionary RTCRtpTransceiverInit {
-   *      RTCRtpTransceiverDirection         direction = "sendrecv";
-   *      sequence<MediaStream>              streams;
-   *      sequence<RTCRtpEncodingParameters> sendEncodings;
-   *  };
+    5.1.  RTCPeerConnection Interface Extensions
+
+      partial interface RTCPeerConnection {
+          sequence<RTCRtpSender>      getSenders();
+          sequence<RTCRtpReceiver>    getReceivers();
+          sequence<RTCRtpTransceiver> getTransceivers();
+          RTCRtpTransceiver           addTransceiver((MediaStreamTrack or DOMString) trackOrKind,
+                                                     optional RTCRtpTransceiverInit init);
+          ...
+      };
+
+      dictionary RTCRtpTransceiverInit {
+          RTCRtpTransceiverDirection         direction = "sendrecv";
+          sequence<MediaStream>              streams;
+          sequence<RTCRtpEncodingParameters> sendEncodings;
+      };
+
+      enum RTCRtpTransceiverDirection {
+        "sendrecv",
+        "sendonly",
+        "recvonly",
+        "inactive"
+      };
+
+    5.2.  RTCRtpSender Interface
+
+      interface RTCRtpSender {
+        readonly attribute MediaStreamTrack? track;
+        ...
+      };
+
+    5.3.  RTCRtpReceiver Interface
+
+      interface RTCRtpReceiver {
+        readonly attribute MediaStreamTrack  track;
+        ...
+      };
+
+    5.4.  RTCRtpTransceiver Interface
+
+      interface RTCRtpTransceiver {
+        readonly attribute DOMString?                  mid;
+        [SameObject]
+        readonly attribute RTCRtpSender                sender;
+        [SameObject]
+        readonly attribute RTCRtpReceiver              receiver;
+        readonly attribute boolean                     stopped;
+        readonly attribute RTCRtpTransceiverDirection  direction;
+        readonly attribute RTCRtpTransceiverDirection? currentDirection;
+        ...
+      };
 
       Note
         While addTrack checks if the MediaStreamTrack given as an argument is
@@ -38,34 +74,54 @@
    */
 
   /*
-   *  5.1.  addTransceiver
-   *        The initial value of mid is null.
-   *
-   *        3.  If the first argument is a string, let it be kind and run the following steps:
-   *            2.  Let track be null.
-   *        7.  Create an RTCRtpSender with track, streams and sendEncodings and let sender
-   *            be the result.
-   *        8.  Create an RTCRtpReceiver with kind and let receiver be the result.
-   *        9.  Create an RTCRtpTransceiver with sender and receiver and let transceiver
-   *            be the result.
-   *        10. Add transceiver to connection's set of transceivers.
-   *
-   *  5.3.  RTCRtpReceiver Interface
-   *        Create an RTCRtpReceiver
-   *        2.  Let track be a new MediaStreamTrack object [GETUSERMEDIA]. The source of
-   *            track is a remote source provided by receiver.
-   *        3.  Initialize track.kind to kind.
-   *        5.  Initialize track.label to the result of concatenating the string "remote "
-   *            with kind.
-   *        6.  Initialize track.readyState to live.
-   *        7.  Initialize track.muted to true.
-   *        8.  Set receiver.track to track.
-   *
-   *  5.4.  RTCRtpTransceiver Interface
-   *        Create an RTCRtpTransceiver
-   *        2.  Set transceiver.sender to sender.
-   *        3.  Set transceiver.receiver to receiver.
-   *        4.  Set transceiver.stopped to false.
+    5.1.  addTransceiver
+      3.  If the first argument is a string, let it be kind and run the following steps:
+        1.  If kind is not a legal MediaStreamTrack kind, throw a TypeError.
+   */
+  test(t => {
+    const pc = new RTCPeerConnection();
+    assert_own_property(pc, 'addTransceiver');
+    assert_throws(new TypeError(), () => pc.addTransceiver('invalid'));
+  }, 'addTransceiver() with string argument as invalid kind should throw TypeError');
+
+  /*
+    5.1.  addTransceiver
+      The initial value of mid is null.
+
+      3.  If the dictionary argument is present, let direction be the value of the
+          direction member. Otherwise let direction be sendrecv.
+      4.  If the first argument is a string, let it be kind and run the following steps:
+        2.  Let track be null.
+      8.  Create an RTCRtpSender with track, streams and sendEncodings and let
+          sender be the result.
+      9.  Create an RTCRtpReceiver with kind and let receiver be the result.
+      10. Create an RTCRtpTransceiver with sender, receiver and direction, and let
+          transceiver be the result.
+      11. Add transceiver to connection's set of transceivers.
+
+    5.2.  RTCRtpSender Interface
+      Create an RTCRtpSender
+        2.  Set sender.track to track.
+
+    5.3.  RTCRtpReceiver Interface
+      Create an RTCRtpReceiver
+        2.  Let track be a new MediaStreamTrack object [GETUSERMEDIA]. The source of
+            track is a remote source provided by receiver.
+        3.  Initialize track.kind to kind.
+        5.  Initialize track.label to the result of concatenating the string "remote "
+            with kind.
+        6.  Initialize track.readyState to live.
+        7.  Initialize track.muted to true.
+        8.  Set receiver.track to track.
+
+    5.4.  RTCRtpTransceiver Interface
+      Create an RTCRtpTransceiver
+        2.  Set transceiver.sender to sender.
+        3.  Set transceiver.receiver to receiver.
+        4.  Let transceiver have a [[Direction]] internal slot, initialized to direction.
+        5.  Let transceiver have a [[CurrentDirection]] internal slot, initialized
+            to null.
+        6.  Set transceiver.stopped to false.
    */
   test(t => {
     const pc = new RTCPeerConnection();
@@ -79,6 +135,7 @@
     assert_equals(transceiver.mid, null);
     assert_equals(transceiver.stopped, false);
     assert_equals(transceiver.direction, 'sendrecv');
+    assert_equals(transceiver.currentDirection, null);
 
     assert_array_equals([transceiver], pc.getTransceivers(),
       `Expect added transceiver to be the only element in connection's list of transceivers`);
@@ -155,23 +212,29 @@
 
   }, `addTransceiver('video') should return a video transceiver`);
 
-  /*
-   *  5.1.  addTransceiver
-   *        3.1.  If kind is not a legal MediaStreamTrack kind, throw a TypeError.
-   */
+  test(t => {
+    const pc = new RTCPeerConnection();
+    const transceiver = pc.addTransceiver('audio', { direction: 'sendonly' });
+    assert_equals(transceiver.direction, 'sendonly');
+  }, `addTransceiver() with direction sendonly should have result transceiver.direction be the same`);
+
+  test(t => {
+    const pc = new RTCPeerConnection();
+    const transceiver = pc.addTransceiver('audio', { direction: 'inactive' });
+    assert_equals(transceiver.direction, 'inactive');
+  }, `addTransceiver() with direction inactive should have result transceiver.direction be the same`);
+
   test(t => {
     const pc = new RTCPeerConnection();
     assert_own_property(pc, 'addTransceiver');
-    assert_throws(new TypeError(), () => pc.addTransceiver('invalid'));
-  }, 'addTransceiver() with string argument as invalid kind should throw TypeError');
+    assert_throws(new TypeError(), () =>
+      pc.addTransceiver('audio', { direction: 'invalid' }));
+  }, `addTransceiver() with invalid direction should throw TypeError`);
 
   /*
     5.1.  addTransceiver
-      3.  If the first argument is a MediaStreamTrack , let it be track and let
+      5.  If the first argument is a MediaStreamTrack , let it be track and let
           kind be track.kind.
-      7.  Create an RTCRtpSender with track, streams and sendEncodings and let sender
-          be the result.
-      8.  Create an RTCRtpReceiver with kind and let receiver be the result.
    */
   test(t => {
     const pc = new RTCPeerConnection();
@@ -242,63 +305,84 @@
   /*
     TODO
       5.1.  addTransceiver
-        Adding a transceiver will cause future calls to createOffer to add a media
-        description for the corresponding transceiver, as defined in [JSEP]
-        (section 5.2.2.).
+        - Adding a transceiver will cause future calls to createOffer to add a media
+          description for the corresponding transceiver, as defined in [JSEP]
+          (section 5.2.2.).
 
-        The sendEncodings argument can be used to specify the number of offered
-        simulcast encodings, and optionally their RIDs and encoding parameters.
-        Aside from rid , all read-only parameters in the RTCRtpEncodingParameters
-        dictionaries, such as ssrc , must be left unset, or an error will be thrown.
+        - Setting a new RTCSessionDescription may change mid to a non-null value,
+          as defined in [JSEP] (section 5.5. and section 5.6.).
+
+        - The sendEncodings argument can be used to specify the number of offered
+          simulcast encodings, and optionally their RIDs and encoding parameters.
+          Aside from rid , all read-only parameters in the RTCRtpEncodingParameters
+          dictionaries, such as ssrc, must be left unset, or an error will be thrown.
 
         1.  If the dictionary argument is present, and it has a streams member, let
             streams be that list of MediaStream objects.
+
         2.  If the dictionary argument is present, and it has a sendEncodings member,
             let sendEncodings be that list of RTCRtpEncodingParameters objects.
-        5.  Verify that each rid value in sendEncodings is composed only of
-            case-sensitive alphanumeric characters (a-z, A-Z, 0-9) up to a
-            maximum of 16 characters. If one of the RIDs does not meet these
-            requirements, throw a TypeError.
-        6.  If any RTCRtpEncodingParameters dictionary in sendEncodings contains
-            a read-only parameter other than rid, throw an InvalidAccessError.
-        7.  If sendEncodings is set, then subsequent calls to createOffer will be
+
+        6.  Verify that each rid value in sendEncodings is composed only of
+            case-sensitive alphanumeric characters (a-z, A-Z, 0-9) up to a maximum
+            of 16 characters. If one of the RIDs does not meet these requirements,
+            throw a TypeError.
+
+        7.  If any RTCRtpEncodingParameters dictionary in sendEncodings contains
+            a read-only parameter other than rid , throw an InvalidAccessError.
+
+      5.2.  RTCRtpSender Interface
+        Create an RTCRtpSender
+          3.  Let sender have an [[associated MediaStreams]] internal slot, representing
+              a list of MediaStream objects that the MediaStreamTrack object of this
+              sender is associated with.
+
+          4.  Set sender's [[associated MediaStreams]] slot to streams.
+
+          5.  Let sender have a [[send encodings]] internal slot, representing a list
+              of RTCRtpEncodingParameters dictionaries.
+
+          6.  If sendEncodings is given as input to this algorithm, and is non-empty,
+              set the [[send encodings]] slot to sendEncodings. Otherwise, set it to a
+              list containing a single RTCRtpEncodingParameters with active set to true.
+
+      5.3.  RTCRtpReceiver Interface
+        Create an RTCRtpReceiver
+          4.  If an id string, id, was given as input to this algorithm, initialize
+              track.id to id. (Otherwise the value generated when track was created
+              will be used.)
+
+    Tested in RTCPeerConnection-onnegotiationneeded.html
+      5.1.  addTransceiver
+        12. Update the negotiation-needed flag for connection.
+
+    Out of Scope
+      5.1.  addTransceiver
+        8.  If sendEncodings is set, then subsequent calls to createOffer will be
             configured to send multiple RTP encodings as defined in [JSEP]
-            (section 5.2.2. and section 5.2.1.). When setRemoteDescription is called
-            with a corresponding remote description that is able to receive multiple
-            RTP encodings as defined in [JSEP] (section 3.7.), the RTCRtpSender may
-            send multiple RTP encodings and the parameters retrieved via the
-            transceiver's sender.getParameters() will reflect the encodings
-            negotiated.
-        8.  This specification does not define how to configure createOffer to
+            (section 5.2.2. and section 5.2.1.).
+
+            When setRemoteDescription is called with a corresponding remote
+            description that is able to receive multiple RTP encodings as defined
+            in [JSEP] (section 3.7.), the RTCRtpSender may send multiple RTP
+            encodings and the parameters retrieved via the transceiver's
+            sender.getParameters() will reflect the encodings negotiated.
+
+        9.  This specification does not define how to configure createOffer to
             receive multiple RTP encodings. However when setRemoteDescription is
             called with a corresponding remote description that is able to send
             multiple RTP encodings as defined in [JSEP], the RTCRtpReceiver may
             receive multiple RTP encodings and the parameters retrieved via the
             transceiver's receiver.getParameters() will reflect the encodings
             negotiated.
-      5.3.  RTCRtpReceiver Interface
-        Create an RTCRtpReceiver
-        4.  If an id string, id, was given as input to this algorithm, initialize
-            track.id to id. (Otherwise the value generated when track was created
-            will be used.)
 
-    Non-testable
-      5.2.  RTCRtpSender Interface
-        create an RTCRtpSender
-          3.  Let sender have an [[associated MediaStreams]] internal slot,
-              representing a list of MediaStream objects that the MediaStreamTrack
-              object of this sender is associated with.
-          4.  Set sender's [[associated MediaStreams]] slot to streams.
-          5.  Let sender have a [[send encodings]] internal slot, representing a
-              list of RTCRtpEncodingParameters dictionaries.
-          6.  If sendEncodings is given as input to this algorithm, and is non-empty,
-              set the [[send encodings]] slot to sendEncodings. Otherwise, set it
-              to a list containing a single RTCRtpEncodingParameters with active
-              set to true.
+    Coverage Report
+                            Tested    Not-Tested  Non-Testable  Total
+      addTransceiver          11          4           3           18
+      Create Sender            3          4           0            7
+      Create Receiver          8          1           0            9
+      Create Transceiver       7          0           0            7
 
-    Tested in RTCPeerConnection-onnegotiationneeded.html
-      5.1.  addTransceiver
-        11. Update the negotiation-needed flag for connection.
+      Total                   29          9           3           41
    */
-
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor-expected.txt
index 2621126a..5a78522e 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 65 tests; 54 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 59 tests; 48 PASS, 11 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS RTCPeerConnection.length 
 PASS new RTCPeerConnection() 
 PASS new RTCPeerConnection(null) 
@@ -29,7 +29,13 @@
 PASS new RTCPeerConnection({ iceServers: [{ urls: "turns:turn.example.org", username: "user" }] }) 
 PASS new RTCPeerConnection({ iceServers: [{ urls: "turns:turn.example.org", credential: "cred" }] }) 
 PASS new RTCPeerConnection({ iceServers: [{ urls: "relative-url" }] }) 
-PASS new RTCPeerConnection({ iceServers: [{ urls: "http://example.com" }] }) 
+PASS new RTCPeerConnection({ iceServers: [{ urls: ["stun:stun1.example.net", "relative-url"] }] }) 
+FAIL new RTCPeerConnection({ iceServers: [{ urls: "http://example.com" }] }) assert_throws: function "function () {
+        eval(expr);
+      }" threw object "SyntaxError: Failed to construct 'RTCPeerConnection': 'http' is not one of the supported URL schemes 'stun', 'turn' or 'turns'." that is not a DOMException NotSupportedError: property "code" is equal to 12, expected 9
+FAIL new RTCPeerConnection({ iceServers: [{ urls: ["stun:stun1.example.net", "http://example.com"] }] }) assert_throws: function "function () {
+        eval(expr);
+      }" threw object "SyntaxError: Failed to construct 'RTCPeerConnection': 'http' is not one of the supported URL schemes 'stun', 'turn' or 'turns'." that is not a DOMException NotSupportedError: property "code" is equal to 12, expected 9
 PASS new RTCPeerConnection({ iceServers: [{ urls: [], credentialType: "password" }] }) 
 PASS new RTCPeerConnection({ iceServers: [{ urls: [], credentialType: "token" }] }) 
 FAIL new RTCPeerConnection({ iceServers: [{ urls: [], credentialType: "invalid" }] }) assert_throws: function "function () {
@@ -38,14 +44,6 @@
 FAIL new RTCPeerConnection({ iceServers: [{ url: "stun:stun1.example.net" }] }) assert_throws: function "function () {
         eval(expr);
       }" did not throw
-PASS new RTCPeerConnection({ iceTransportPolicy: null }) 
-PASS new RTCPeerConnection({ iceTransportPolicy: undefined }) 
-PASS new RTCPeerConnection({ iceTransportPolicy: "relay" }) 
-PASS new RTCPeerConnection({ iceTransportPolicy: "all" }) 
-PASS new RTCPeerConnection({ iceTransportPolicy: "invalid" }) 
-PASS new RTCPeerConnection({ iceTransportPolicy: "none" }) 
-FAIL new RTCPeerConnection({ iceTransports: "invalid" }) Failed to construct 'RTCPeerConnection': The provided value 'invalid' is not a valid enum value of type RTCIceTransportPolicy.
-FAIL new RTCPeerConnection({ iceTransports: "none" }) Failed to construct 'RTCPeerConnection': The provided value 'none' is not a valid enum value of type RTCIceTransportPolicy.
 PASS new RTCPeerConnection({ rtcpMuxPolicy: null }) 
 PASS new RTCPeerConnection({ rtcpMuxPolicy: undefined }) 
 PASS new RTCPeerConnection({ rtcpMuxPolicy: "negotiate" }) 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor.html
index d14afaf..910aeb97 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-constructor.html
@@ -49,7 +49,9 @@
   '{ iceServers: [{ urls: "turns:turn.example.org", username: "user" }] }': 'InvalidAccessError',
   '{ iceServers: [{ urls: "turns:turn.example.org", credential: "cred" }] }': 'InvalidAccessError',
   '{ iceServers: [{ urls: "relative-url" }] }': 'SyntaxError',
-  '{ iceServers: [{ urls: "http://example.com" }] }': 'SyntaxError',
+  '{ iceServers: [{ urls: ["stun:stun1.example.net", "relative-url"] }] }': 'SyntaxError',
+  '{ iceServers: [{ urls: "http://example.com" }] }': 'NotSupportedError',
+  '{ iceServers: [{ urls: ["stun:stun1.example.net", "http://example.com"] }] }': 'NotSupportedError',
   // credentialType
   '{ iceServers: [{ urls: [] }] }': false,
   '{ iceServers: [{ urls: [], credentialType: "password" }] }': false,
@@ -58,18 +60,6 @@
   // Blink and Gecko fall back to url, but it's not in the spec.
   '{ iceServers: [{ url: "stun:stun1.example.net" }] }': new TypeError,
 
-  // iceTransportPolicy
-  '{ iceTransportPolicy: null }': new TypeError,
-  '{ iceTransportPolicy: undefined }': false,
-  '{ iceTransportPolicy: "relay" }': false,
-  '{ iceTransportPolicy: "all" }': false,
-  '{ iceTransportPolicy: "invalid" }': new TypeError,
-  // "none" is in Blink and Gecko's IDL, but not in the spec.
-  '{ iceTransportPolicy: "none" }': new TypeError,
-  // iceTransportPolicy is called iceTransports in Blink.
-  '{ iceTransports: "invalid" }': false,
-  '{ iceTransports: "none" }': false,
-
   // rtcpMuxPolicy
   '{ rtcpMuxPolicy: null }': new TypeError,
   '{ rtcpMuxPolicy: undefined }': false,
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-createDataChannel-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-createDataChannel-expected.txt
index b6eb02ef..fac9af0 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-createDataChannel-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-createDataChannel-expected.txt
@@ -1,7 +1,8 @@
 This is a testharness.js-based test.
 PASS createDataChannel with no argument should throw TypeError 
 PASS createDataChannel with closed connection should throw InvalidStateError 
-FAIL createDataChannel attribute default values assert_equals: maxPacketLifeTime expected (object) null but got (undefined) undefined
+FAIL createDataChannel attribute default values assert_equals: expected (object) null but got (undefined) undefined
+FAIL createDataChannel with provided parameters should initialize attributes to provided values assert_equals: expected (object) null but got (undefined) undefined
 PASS createDataChannel with label "foo" should succeed 
 PASS createDataChannel with label null should succeed 
 PASS createDataChannel with label undefined should succeed 
@@ -37,6 +38,7 @@
       protocol: ' '.repeat(65536),
       negotiated: false
     })" did not throw
-PASS createDataChannel with negotiated true and long label and long protocol should succeed 
+FAIL createDataChannel with negotiated true and long label and long protocol should succeed assert_equals: expected "                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                " but got ""
+FAIL Channels created after SCTP transport is established should have id assigned assert_equals: Expect initial id to be null expected (object) null but got (number) 65535
 Harness: the test ran to completion.
 
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-createDataChannel.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-createDataChannel.html
index 1022e8f..a446280 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-createDataChannel.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-createDataChannel.html
@@ -7,7 +7,7 @@
 'use strict';
 
 // Test is based on the following editor draft:
-// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
+// https://rawgit.com/w3c/webrtc-pc/cc8d80f455b86c8041d63bceb8b457f45c72aa89/webrtc.html
 
 /*
   6.1.  RTCPeerConnection Interface Extensions
@@ -19,6 +19,19 @@
     };
 
   6.2.  RTCDataChannel
+
+    interface RTCDataChannel : EventTarget {
+       readonly attribute USVString           label;
+       readonly attribute boolean             ordered;
+       readonly attribute unsigned short?     maxPacketLifeTime;
+       readonly attribute unsigned short?     maxRetransmits;
+       readonly attribute USVString           protocol;
+       readonly attribute boolean             negotiated;
+       readonly attribute unsigned short?     id;
+       readonly attribute RTCPriorityType     priority;
+       readonly attribute RTCDataChannelState readyState;
+    };
+
     dictionary RTCDataChannelInit {
       boolean         ordered = true;
       unsigned short  maxPacketLifeTime;
@@ -29,6 +42,15 @@
       unsigned short  id;
       RTCPriorityType priority = "low";
     };
+
+  4.9.1.  RTCPriorityType Enum
+
+    enum RTCPriorityType {
+      "very-low",
+      "low",
+      "medium",
+      "high"
+    };
  */
 
 test(() => {
@@ -49,33 +71,85 @@
 }, 'createDataChannel with closed connection should throw InvalidStateError');
 
 /*
-  6.2.  createDataChannel
-    4.  Initialize channel's label attribute to the value of the first argument.
-    5.  Set channel's ordered , maxPacketLifeTime , maxRetransmits , protocol,
-        negotiated , id and priority attributes to the values of the corresponding
-        members of the dataChannelDict argument, using a value of null if the
-        corresponding dictionary member is missing.
+  6.1.  createDataChannel
+    4.  Let channel have a [[Label]] internal slot initialized to the value of the
+        first argument.
+    5.  Let options be the second argument.
+    6.  Let channel have an [[MaxPacketLifeTime]] internal slot initialized to
+        option's maxPacketLifeTime member, if present, otherwise null.
+    7.  Let channel have an [[MaxRetransmits]] internal slot initialized to
+        option's maxRetransmits member, if present, otherwise null.
+    8.  Let channel have an [[DataChannelId]] internal slot initialized to
+        option's id member, if present, otherwise null.
+    9.  Let channel have an [[Ordered]] internal slot initialized to option's
+        ordered member.
+    10. Let channel have an [[Protocol]] internal slot initialized to option's
+        protocol member.
+    11. Let channel have an [[Negotiated]] internal slot initialized to option's
+        negotiated member.
+    12. Let channel have an [[DataChannelPriority]] internal slot initialized
+        to option's priority member.
+
+  6.2.  RTCDataChannel
+
+    A RTCDataChannel, created with createDataChannel or dispatched via a
+    RTCDataChannelEvent, MUST initially be in the connecting state
+
+    binaryType
+      When a RTCDataChannel object is created, the binaryType attribute MUST
+      be initialized to the string "blob".
  */
 test(() => {
   const pc = new RTCPeerConnection();
   const channel = pc.createDataChannel('');
   assert_true(channel instanceof RTCDataChannel, 'is RTCDataChannel');
-  assert_equals(channel.label, '', 'label');
-  assert_equals(channel.ordered, true, 'ordered');
-  assert_equals(channel.maxPacketLifeTime, null, 'maxPacketLifeTime');
-  assert_equals(channel.maxRetransmits, null, 'maxRetransmits');
-  assert_equals(channel.protocol, '', 'protocol');
-  assert_equals(channel.negotiated, false, 'negotiated');
+  assert_equals(channel.label, '');
+  assert_equals(channel.ordered, true);
+  assert_equals(channel.maxPacketLifeTime, null);
+  assert_equals(channel.maxRetransmits, null);
+  assert_equals(channel.protocol, '');
+  assert_equals(channel.negotiated, false);
+
   // Since no offer/answer exchange has occurred yet, the DTLS role is unknown
   // and so the ID should be null.
-  assert_equals(channel.id, null, 'id');
-  assert_equals(channel.priority, 'low', 'priority');
+  assert_equals(channel.id, null);
+  assert_equals(channel.priority, 'low');
+
+  assert_equals(channel.readyState, 'connecting');
+  assert_equals(channel.binaryType, 'blob');
+
 }, 'createDataChannel attribute default values');
 
+test(() => {
+  const pc = new RTCPeerConnection();
+  const channel = pc.createDataChannel('test', {
+    ordered: false,
+    maxPacketLifeTime: null,
+    maxRetransmits: 1,
+    protocol: 'custom',
+    negotiated: true,
+    id: 3,
+    priority: 'high'
+  });
+
+  assert_true(channel instanceof RTCDataChannel, 'is RTCDataChannel');
+  assert_equals(channel.label, 'test');
+  assert_equals(channel.ordered, false);
+  assert_equals(channel.maxPacketLifeTime, null);
+  assert_equals(channel.maxRetransmits, 1);
+  assert_equals(channel.protocol, 'custom');
+  assert_equals(channel.negotiated, true);
+  assert_equals(channel.id, 3);
+  assert_equals(channel.priority, 'high');
+  assert_equals(channel.readyState, 'connecting');
+  assert_equals(channel.binaryType, 'blob');
+
+}, 'createDataChannel with provided parameters should initialize attributes to provided values');
 
 /*
   6.2.  createDataChannel
-    4.  Initialize channel's label attribute to the value of the first argument.
+    4.  Let channel have a [[Label]] internal slot initialized to the value of the
+        first argument.
 
   [ECMA262] 7.1.12. ToString(argument)
     undefined -> "undefined"
@@ -99,10 +173,9 @@
 
 /*
   6.2.  RTCDataChannel
-    dictionary RTCDataChannelInit {
-      boolean         ordered = true;
-      ...
-    }
+    createDataChannel
+      9.  Let channel have an [[Ordered]] internal slot initialized to option's
+          ordered member.
  */
 test(() => {
   const pc = new RTCPeerConnection();
@@ -122,10 +195,9 @@
 
 /*
   6.2.  RTCDataChannel
-    dictionary RTCDataChannelInit {
-      unsigned short  maxPacketLifeTime;
-      ...
-    }
+    createDataChannel
+      6.  Let channel have an [[MaxPacketLifeTime]] internal slot initialized to
+          option's maxPacketLifeTime member, if present, otherwise null.
  */
 test(() => {
   const pc = new RTCPeerConnection;
@@ -135,10 +207,9 @@
 
 /*
   6.2.  RTCDataChannel
-    dictionary RTCDataChannelInit {
-      unsigned short  maxRetransmits;
-      ...
-    }
+    createDataChannel
+      7.  Let channel have an [[MaxRetransmits]] internal slot initialized to
+          option's maxRetransmits member, if present, otherwise null.
  */
 test(() => {
   const pc = new RTCPeerConnection;
@@ -148,12 +219,12 @@
 
 /*
   6.2.  createDataChannel
-    8.  If both the maxPacketLifeTime and maxRetransmits attributes are set
-        (not null), throw a SyntaxError.
+    15. If both [[MaxPacketLifeTime]] and [[MaxRetransmits]] attributes are set
+        (not null), throw a TypeError.
  */
 test(() => {
   const pc = new RTCPeerConnection;
-  assert_throws('SyntaxError', () => pc.createDataChannel('', {
+  assert_throws(new TypeError(), () => pc.createDataChannel('', {
     maxPacketLifeTime: 0,
     maxRetransmits: 0
   }));
@@ -161,10 +232,9 @@
 
 /*
   6.2.  RTCDataChannel
-    dictionary RTCDataChannelInit {
-      USVString       protocol = "";
-      ...
-    }
+    createDataChannel
+      10. Let channel have an [[Protocol]] internal slot initialized to option's
+          protocol member.
  */
 const protocols = [
   ['"foo"', 'foo', 'foo'],
@@ -182,10 +252,9 @@
 
 /*
   6.2.  RTCDataChannel
-    dictionary RTCDataChannelInit {
-      boolean         negotiated = false;
-      ...
-    }
+    createDataChannel
+      11. Let channel have an [[Negotiated]] internal slot initialized to option's
+          negotiated member.
  */
 test(() => {
   const pc = new RTCPeerConnection;
@@ -196,12 +265,6 @@
 
 /*
   6.2.  RTCDataChannel
-    dictionary RTCDataChannelInit {
-      [EnforceRange]
-      unsigned short  id;
-      ...
-    }
-
     createDataChannel
       10. If id is equal to 65535, which is greater than the maximum allowed ID
           of 65534 but still qualifies as an unsigned short, throw a TypeError.
@@ -223,18 +286,10 @@
 
 /*
   6.2.  RTCDataChannel
-    dictionary RTCDataChannelInit {
-      RTCPriorityType priority = "low";
-      ...
-    }
+    createDataChannel
+      12. Let channel have an [[DataChannelPriority]] internal slot initialized
+          to option's priority member.
 
-  4.9.1.  RTCPriorityType Enum
-    enum RTCPriorityType {
-      "very-low",
-      "low",
-      "medium",
-      "high"
-    };
  */
 test(() => {
   const pc = new RTCPeerConnection();
@@ -250,9 +305,8 @@
 
 /*
   6.2.  createDataChannel
-    6.  If negotiated is false and label is longer than 65535 bytes long,
-        throw a TypeError.
- */
+    13. If [[Negotiated]] is false and [[Label]] is longer than 65535 bytes
+        long, throw a TypeError.  */
 test(() => {
   const pc = new RTCPeerConnection();
   assert_throws(new TypeError(), () =>
@@ -264,7 +318,7 @@
 
 /*
   6.2.  createDataChannel
-    7.  If negotiated is false and protocol is longer than 65535 bytes long,
+    14. If [[Negotiated]] is false and [[Protocol]] is longer than 65535 bytes long,
         throw a TypeError.
  */
 test(() => {
@@ -278,29 +332,106 @@
 
 test(() => {
   const pc = new RTCPeerConnection();
-  pc.createDataChannel('', {
-    label: ' '.repeat(65536),
+  const label = ' '.repeat(65536)
+
+  const channel = pc.createDataChannel('', {
+    label,
     protocol: ' '.repeat(65536),
     negotiated: true
   });
+
+  assert_equals(channel.label, label);
 }, 'createDataChannel with negotiated true and long label and long protocol should succeed');
 
 /*
-  TODO
+  4.4.1.6.  Set the RTCSessionSessionDescription
+    2.2.6.  If description is of type "answer" or "pranswer", then run the
+            following steps:
+      1.  If description initiates the establishment of a new SCTP association,
+          as defined in [SCTP-SDP], Sections 10.3 and 10.4, set the value of
+          connection's [[sctpTransport]] internal slot to a newly created RTCSctpTransport.
+      2.  If description negotiates the DTLS role of the SCTP transport, and
+          there is an RTCDataChannel with a null id, then generate an ID according
+          to [RTCWEB-DATA-PROTOCOL].
+
   6.2.  createDataChannel
-    11. If the id attribute is null (due to no ID being passed into
+    18. If the [[DataChannelId]] slot is null (due to no ID being passed into
         createDataChannel), and the DTLS role of the SCTP transport has already
-        been negotiated, then initialize id to a value generated by the user
-        agent, according to [RTCWEB-DATA-PROTOCOL], and skip to the next step.
-        If no available ID could be generated, or if the value of the id member
-        of the dictionary is taken by an existing RTCDataChannel , throw a
-        ResourceInUse exception.
+        been negotiated, then initialize [[DataChannelId]] to a value generated
+        by the user agent, according to [RTCWEB-DATA-PROTOCOL].
+ */
+promise_test(t => {
+  const pc = new RTCPeerConnection();
+  const channel1 = pc.createDataChannel('channel');
+  assert_equals(channel1.id, null,
+    'Expect initial id to be null');
+
+  return pc.createOffer()
+  .then(offer =>
+    pc.setLocalDescription(offer)
+    .then(() => generateAnswer(offer)))
+  .then(answer => pc.setRemoteDescription(answer))
+  .then(() => {
+    assert_not_equals(channel1.id, null,
+      'Expect channel1.id to be assigned');
+
+    assert_greater_than_equals(channel1.id, 0,
+      'Expect channel1.id to be set to valid unsigned short');
+
+    assert_less_than(channel1.id, 65535,
+      'Expect channel1.id to be set to valid unsigned short');
+
+    const channel2 = pc.createDataChannel('channel');
+
+    assert_not_equals(channel2.id, null,
+      'Expect channel2.id to be assigned');
+
+    assert_greater_than_equals(channel2.id, 0,
+      'Expect channel2.id to be set to valid unsigned short');
+
+    assert_less_than(channel2.id, 65535,
+      'Expect channel2.id to be set to valid unsigned short');
+
+    assert_not_equals(channel2, channel1,
+      'Expect channels created from same label to be different');
+
+    assert_equals(channel2.label, channel1.label,
+      'Expect different channnels can have the same label but different id');
+
+    assert_not_equals(channel2.id, channel1.id,
+      'Expect different channnels can have the same label but different id');
+  });
+}, 'Channels created after SCTP transport is established should have id assigned');
+
+/*
+  TODO
+    6.1.  createDataChannel
+      18. If no available ID could be generated, or if the value of the
+          id member of the dictionary is taken by an existing RTCDataChannel, throw
+          a ResourceInUse exception.
 
   Untestable
-  6.2.  createDataChannel
-    9.  If an attribute, either maxPacketLifeTime or maxRetransmits , has been
-        set to indicate unreliable mode, and that value exceeds the maximum
-        value supported by the user agent, the value must be set to the user
-        agents maximum value.
- */
+    6.1.  createDataChannel
+      16. If a setting, either [[MaxPacketLifeTime]] or [[MaxRetransmits]], has
+          been set to indicate unreliable mode, and that value exceeds the maximum
+          value supported by the user agent, the value MUST be set to the user
+          agents maximum value.
+
+      20. Create channel's associated underlying data transport and configure
+          it according to the relevant properties of channel.
+
+  Tested in RTCPeerConnection-onnegotiationneeded.html
+    21. If channel was the first RTCDataChannel created on connection, update
+        the negotiation-needed flag for connection.
+
+  Issues
+    w3c/webrtc-pc#1412
+      ResourceInUse exception is not defined
+
+  Coverage Report
+    Tested        22
+    Not Tested     1
+    Untestable     2
+    Total         25
+*/
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-onnegotiationneeded.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-onnegotiationneeded.html
index 6d0fe6f..fb9fcbf31 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-onnegotiationneeded.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-onnegotiationneeded.html
@@ -7,7 +7,7 @@
   'use strict';
 
   // Test is based on the following editor draft:
-  // https://w3c.github.io/webrtc-pc/archives/20170515/webrtc.html
+  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
 
   /* Helper Functions */
 
@@ -212,15 +212,13 @@
   }, 'negotiationneeded event should not fire if signaling state is not stable');
 
   /*
-    4.3.1.  RTCPeerConnection Operation
-      To set an RTCSessionDescription description
-        10. If connection's signaling state is now stable, update the
-            negotiation-needed flag. If connection's [[needNegotiation]] slot
-            was true both before and after this update, queue a task that runs
-            the following steps:
-          1.  If connection's [[isClosed]] slot is true, abort these steps.
-          2.  If connection's [[needNegotiation]] slot is false, abort these steps.
-          3.  Fire a simple event named negotiationneeded at connection.
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.2.10. If connection's signaling state is now stable, update the negotiation-needed
+              flag. If connection's [[NegotiationNeeded]] slot was true both before and after
+              this update, queue a task that runs the following steps:
+        1.  If connection's [[IsClosed]] slot is true, abort these steps.
+        2.  If connection's [[NegotiationNeeded]] slot is false, abort these steps.
+        3.  Fire a simple event named negotiationneeded at connection.
    */
   promise_test(t => {
     const pc = new RTCPeerConnection();
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-ontrack-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-ontrack-expected.txt
new file mode 100644
index 0000000..666bd2c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-ontrack-expected.txt
@@ -0,0 +1,4 @@
+This is a testharness.js-based test.
+FAIL setRemoteDescription should trigger ontrack event when the MSID of the stream is is parsed. assert_own_property: Expect pc to have ontrack event handler attribute expected property "ontrack" missing
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-ontrack.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-ontrack.html
new file mode 100644
index 0000000..22e9d280
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-ontrack.html
@@ -0,0 +1,49 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>RTCPeerConnection.prototype.ontrack</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+  'use strict';
+
+  // tests that ontrack is called and parses the msid information from the SDP and creates
+  // the streams with matching identifiers.
+  async_test(t => {
+    const pc = new RTCPeerConnection();
+
+    // Fail the test if the ontrack event handler is not implemented
+    assert_own_property(pc, 'ontrack', 'Expect pc to have ontrack event handler attribute');
+
+    const sdp = `v=0
+o=- 166855176514521964 2 IN IP4 127.0.0.1
+s=-
+t=0 0
+a=msid-semantic:WMS *
+m=audio 9 UDP/TLS/RTP/SAVPF 111
+c=IN IP4 0.0.0.0
+a=rtcp:9 IN IP4 0.0.0.0
+a=ice-ufrag:someufrag
+a=ice-pwd:somelongpwdwithenoughrandomness
+a=fingerprint:sha-256 8C:71:B3:8D:A5:38:FD:8F:A4:2E:A2:65:6C:86:52:BC:E0:6E:94:F2:9F:7C:4D:B5:DF:AF:AA:6F:44:90:8D:F4
+a=setup:actpass
+a=rtcp-mux
+a=mid:mid1
+a=sendonly
+a=rtpmap:111 opus/48000/2
+a=msid:stream1 track1
+a=ssrc:1001 cname:some
+`;
+
+    pc.ontrack = t.step_func(event => {
+      assert_equals(event.streams.length, 1, 'the track belongs to one MediaStream');
+      assert_equals(event.streams[0].id, 'stream1', 'the stream name is parsed from the MSID line');
+      t.done();
+    });
+
+    pc.setRemoteDescription(new RTCSessionDescription({type: 'offer', sdp: sdp}))
+    .catch(t.step_func(err => {
+      assert_unreached('Error ' + err.name + ': ' + err.message);
+    }));
+  }, 'setRemoteDescription should trigger ontrack event when the MSID of the stream is is parsed.');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack-expected.txt
index dfa9254f..f2a3912b 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack-expected.txt
@@ -1,8 +1,12 @@
 This is a testharness.js-based test.
-FAIL Calling removeTrack when connection is closed should throw InvalidStateError assert_own_property: Expect pc to have addTransceiver() method expected property "addTransceiver" missing
-FAIL Calling removeTrack on different connection that is closed should throw InvalidStateError assert_own_property: Expect pc to have addTransceiver() method expected property "addTransceiver" missing
-FAIL Calling removeTrack on different connection should throw InvalidAccessError assert_own_property: Expect pc to have addTransceiver() method expected property "addTransceiver" missing
-FAIL Calling removeTrack with valid sender should set sender.track to null assert_own_property: Expect pc to have addTransceiver() method expected property "addTransceiver" missing
+FAIL addTransceiver - Calling removeTrack when connection is closed should throw InvalidStateError assert_own_property: Expect pc to have addTransceiver() method expected property "addTransceiver" missing
+FAIL addTrack - Calling removeTrack when connection is closed should throw InvalidStateError promise_test: Unhandled rejection with value: object "NotSupportedError: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV)."
+FAIL addTransceiver - Calling removeTrack on different connection that is closed should throw InvalidStateError assert_own_property: Expect pc to have addTransceiver() method expected property "addTransceiver" missing
+FAIL addTrack - Calling removeTrack on different connection that is closed should throw InvalidStateError promise_test: Unhandled rejection with value: object "NotSupportedError: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV)."
+FAIL addTransceiver - Calling removeTrack on different connection should throw InvalidAccessError assert_own_property: Expect pc to have addTransceiver() method expected property "addTransceiver" missing
+FAIL addTrack - Calling removeTrack on different connection should throw InvalidAccessError promise_test: Unhandled rejection with value: object "NotSupportedError: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV)."
+FAIL addTransceiver - Calling removeTrack with valid sender should set sender.track to null assert_own_property: Expect pc to have addTransceiver() method expected property "addTransceiver" missing
+FAIL addTrack - Calling removeTrack with valid sender should set sender.track to null promise_test: Unhandled rejection with value: object "NotSupportedError: Only secure origins are allowed (see: https://goo.gl/Y0ZkNV)."
 FAIL Calling removeTrack with currentDirection sendrecv should set direction to recvonly assert_own_property: Expect pc to have addTransceiver() method expected property "addTransceiver" missing
 FAIL Calling removeTrack with currentDirection sendonly should set direction to inactive assert_own_property: Expect pc to have addTransceiver() method expected property "addTransceiver" missing
 FAIL Calling removeTrack with currentDirection recvonly should not change direction assert_own_property: Expect pc to have addTransceiver() method expected property "addTransceiver" missing
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack.html
index 85ffc63d8..e2da02b 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-removeTrack.html
@@ -24,6 +24,13 @@
       };
    */
 
+  // Before calling removeTrack can be tested, one needs to add MediaStreamTracks to
+  // a peer connection. There are two ways for adding MediaStreamTrack: addTrack and
+  // addTransceiver. addTransceiver is a newer API while addTrack has been implemented
+  // in current browsers for some time. As a result some of the removeTrack tests have
+  // two versions so that removeTrack can be partially tested without addTransceiver
+  // and the transceiver APIs being implemented.
+
   /*
     5.1.  removeTrack
       3.  If connection's [[isClosed]] slot is true, throw an InvalidStateError.
@@ -37,7 +44,24 @@
     pc.close();
     assert_throws('InvalidStateError', () => pc.removeTrack(sender));
 
-  }, 'Calling removeTrack when connection is closed should throw InvalidStateError');
+  }, 'addTransceiver - Calling removeTrack when connection is closed should throw InvalidStateError');
+
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+
+    return navigator.mediaDevices.getUserMedia({ audio: true })
+    .then(mediaStream => {
+      const tracks = mediaStream.getTracks();
+      assert_greater_than(tracks.length, 0,
+        'Expect getUserMedia to return at least one audio track');
+
+      const track = tracks[0];
+      const sender = pc.addTrack(track, mediaStream);
+
+      pc.close();
+      assert_throws('InvalidStateError', () => pc.removeTrack(sender));
+    });
+  }, 'addTrack - Calling removeTrack when connection is closed should throw InvalidStateError');
 
   test(t => {
     const pc = new RTCPeerConnection();
@@ -49,7 +73,25 @@
     pc2.close();
     assert_throws('InvalidStateError', () => pc2.removeTrack(sender));
 
-  }, 'Calling removeTrack on different connection that is closed should throw InvalidStateError');
+  }, 'addTransceiver - Calling removeTrack on different connection that is closed should throw InvalidStateError');
+
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+
+    return navigator.mediaDevices.getUserMedia({ audio: true })
+    .then(mediaStream => {
+      const tracks = mediaStream.getTracks();
+      assert_greater_than(tracks.length, 0,
+        'Expect getUserMedia to return at least one audio track');
+
+      const track = tracks[0];
+      const sender = pc.addTrack(track, mediaStream);
+
+      const pc2 = new RTCPeerConnection();
+      pc2.close();
+      assert_throws('InvalidStateError', () => pc2.removeTrack(sender));
+    });
+  }, 'addTrack - Calling removeTrack on different connection that is closed should throw InvalidStateError');
 
   /*
     5.1.  removeTrack
@@ -64,7 +106,24 @@
     const pc2 = new RTCPeerConnection();
     assert_throws('InvalidAccessError', () => pc2.removeTrack(sender));
 
-  }, 'Calling removeTrack on different connection should throw InvalidAccessError');
+  }, 'addTransceiver - Calling removeTrack on different connection should throw InvalidAccessError');
+
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+
+    return navigator.mediaDevices.getUserMedia({ audio: true })
+    .then(mediaStream => {
+      const tracks = mediaStream.getTracks();
+      assert_greater_than(tracks.length, 0,
+        'Expect getUserMedia to return at least one audio track');
+
+      const track = tracks[0];
+      const sender = pc.addTrack(track, mediaStream);
+
+      const pc2 = new RTCPeerConnection();
+      assert_throws('InvalidAccessError', () => pc2.removeTrack(sender));
+    });
+  }, 'addTrack - Calling removeTrack on different connection should throw InvalidAccessError')
 
   /*
     5.1.  removeTrack
@@ -85,7 +144,26 @@
     assert_equals(transceiver.direction, 'sendrecv',
       'direction should not be altered');
 
-  }, 'Calling removeTrack with valid sender should set sender.track to null');
+  }, 'addTransceiver - Calling removeTrack with valid sender should set sender.track to null');
+
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+
+    return navigator.mediaDevices.getUserMedia({ audio: true })
+    .then(mediaStream => {
+      const tracks = mediaStream.getTracks();
+      assert_greater_than(tracks.length, 0,
+        'Expect getUserMedia to return at least one audio track');
+
+      const track = tracks[0];
+      const sender = pc.addTrack(track, mediaStream);
+
+      assert_equals(sender.track, track);
+
+      pc.removeTrack(sender);
+      assert_equals(sender.track, null);
+    });
+  }, 'addTrack - Calling removeTrack with valid sender should set sender.track to null');
 
   /*
     5.1.  removeTrack
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setLocalDescription-pranswer.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setLocalDescription-pranswer.html
new file mode 100644
index 0000000..46fe881
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setLocalDescription-pranswer.html
@@ -0,0 +1,153 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>RTCPeerConnection.prototype.setLocalDescription pranswer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="RTCPeerConnection-helper.js"></script>
+<script>
+  'use strict';
+
+  // Test is based on the following editor draft:
+  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
+
+  // The following helper functions are called from RTCPeerConnection-helper.js:
+  //   generateOffer
+  //   generateAnswer
+  //   assert_session_desc_equals
+  //   test_state_change_event
+
+  /*
+    4.3.2.  Interface Definition
+      [Constructor(optional RTCConfiguration configuration)]
+      interface RTCPeerConnection : EventTarget {
+        Promise<void>                      setLocalDescription(
+            RTCSessionDescriptionInit description);
+
+        readonly attribute RTCSessionDescription? localDescription;
+        readonly attribute RTCSessionDescription? currentLocalDescription;
+        readonly attribute RTCSessionDescription? pendingLocalDescription;
+
+        Promise<void>                      setRemoteDescription(
+            RTCSessionDescriptionInit description);
+
+        readonly attribute RTCSessionDescription? remoteDescription;
+        readonly attribute RTCSessionDescription? currentRemoteDescription;
+        readonly attribute RTCSessionDescription? pendingRemoteDescription;
+        ...
+      };
+
+    4.6.2.  RTCSessionDescription Class
+      dictionary RTCSessionDescriptionInit {
+        required RTCSdpType type;
+                 DOMString  sdp = "";
+      };
+
+    4.6.1.  RTCSdpType
+      enum RTCSdpType {
+        "offer",
+        "pranswer",
+        "answer",
+        "rollback"
+      };
+   */
+
+  /*
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.3.  If the description's type is invalid for the current signaling state of
+            connection, then reject p with a newly created InvalidStateError and abort
+            these steps.
+
+    [jsep]
+      5.5. If the type is "pranswer" or "answer", the PeerConnection
+           state MUST be either "have-remote-offer" or "have-local-pranswer".
+   */
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+
+    return generateOffer()
+    .then(offer =>
+      promise_rejects(t, 'InvalidStateError',
+        pc.setLocalDescription({ type: 'pranswer', sdp: offer.sdp })));
+
+  }, 'setLocalDescription(pranswer) from stable state should reject with InvalidStateError');
+
+  /*
+    4.3.1.6 Set the RTCSessionSessionDescription
+      2.2.2.  If description is set as a local description, then run one of the
+              following steps:
+        - If description is of type "pranswer", then set
+          connection.pendingLocalDescription to description and signaling state to
+          have-local-pranswer.
+   */
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+    test_state_change_event(t, pc, ['have-remote-offer', 'have-local-pranswer']);
+
+    return generateOffer({ video: true })
+    .then(offer =>
+      pc.setRemoteDescription(offer)
+      .then(() => pc.createAnswer())
+      .then(answer => {
+        const pranswer = { type: 'pranswer', sdp: answer.sdp };
+
+        return pc.setLocalDescription(pranswer)
+        .then(() => {
+          assert_equals(pc.signalingState, 'have-local-pranswer');
+
+          assert_session_desc_equals(pc.remoteDescription, offer);
+          assert_session_desc_equals(pc.pendingRemoteDescription, offer);
+          assert_equals(pc.currentRemoteDescription, null);
+
+          assert_session_desc_equals(pc.localDescription, pranswer);
+          assert_session_desc_equals(pc.pendingLocalDescription, pranswer);
+          assert_equals(pc.currentLocalDescription, null);
+
+          assert_equals(pc.pendingRemoteDescription, null);
+        });
+      }));
+  }, 'setLocalDescription(pranswer) should succeed');
+
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+    test_state_change_event(t, pc, ['have-remote-offer', 'have-local-pranswer']);
+
+    return generateOffer({ video: true })
+    .then(offer =>
+      pc.setRemoteDescription(offer)
+      .then(() => pc.createAnswer())
+      .then(answer => {
+        const pranswer = { type: 'pranswer', sdp: answer.sdp };
+
+        return pc.setLocalDescription(pranswer)
+        .then(() => pc.setLocalDescription(pranswer));
+      }));
+  }, 'setLocalDescription(pranswer) can be applied multiple times while still in have-local-pranswer');
+
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+    test_state_change_event(t, pc, ['have-remote-offer', 'have-local-pranswer', 'stable']);
+
+    return generateOffer({ video: true })
+    .then(offer =>
+      pc.setRemoteDescription(offer)
+      .then(() => pc.createAnswer())
+      .then(answer => {
+        const pranswer = { type: 'pranswer', sdp: answer.sdp };
+
+        return pc.setLocalDescription(pranswer)
+        .then(() => pc.setLocalDescription(answer))
+        .then(() => {
+          assert_equals(pc.signalingState, 'stable');
+          assert_session_desc_equals(pc.localDescription, answer);
+          assert_session_desc_equals(pc.remoteDescription, offer);
+
+          assert_session_desc_equals(pc.currentLocalDescription, answer);
+          assert_session_desc_equals(pc.currentRemoteDescription, offer);
+
+          assert_equals(pc.pendingLocalDescription, null);
+          assert_equals(pc.pendingRemoteDescription, null);
+        });
+      }));
+  }, 'setLocalDescription(answer) from have-local-pranswer state should succeed');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setLocalDescription-rollback.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setLocalDescription-rollback.html
new file mode 100644
index 0000000..dc2904e0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setLocalDescription-rollback.html
@@ -0,0 +1,82 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>RTCPeerConnection.prototype.setLocalDescription rollback</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="RTCPeerConnection-helper.js"></script>
+<script>
+  'use strict';
+
+  // Test is based on the following editor draft:
+  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
+
+  // The following helper functions are called from RTCPeerConnection-helper.js:
+  //   assert_session_desc_equals
+  //   test_state_change_event
+
+  /*
+    4.3.2.  Interface Definition
+      [Constructor(optional RTCConfiguration configuration)]
+      interface RTCPeerConnection : EventTarget {
+        Promise<void>                      setLocalDescription(
+            RTCSessionDescriptionInit description);
+
+        readonly attribute RTCSessionDescription? localDescription;
+        readonly attribute RTCSessionDescription? currentLocalDescription;
+        readonly attribute RTCSessionDescription? pendingLocalDescription;
+
+        Promise<void>                      setRemoteDescription(
+            RTCSessionDescriptionInit description);
+
+        readonly attribute RTCSessionDescription? remoteDescription;
+        readonly attribute RTCSessionDescription? currentRemoteDescription;
+        readonly attribute RTCSessionDescription? pendingRemoteDescription;
+        ...
+      };
+
+    4.6.2.  RTCSessionDescription Class
+      dictionary RTCSessionDescriptionInit {
+        required RTCSdpType type;
+                 DOMString  sdp = "";
+      };
+
+    4.6.1.  RTCSdpType
+      enum RTCSdpType {
+        "offer",
+        "pranswer",
+        "answer",
+        "rollback"
+      };
+   */
+
+  /*
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.2.2.  If description is set as a local description, then run one of the
+              following steps:
+        - If description is of type "rollback", then this is a rollback. Set
+          connection.pendingLocalDescription to null and signaling state to stable.
+   */
+  promise_test(t=> {
+    const pc = new RTCPeerConnection();
+
+    test_state_change_event(t, pc, ['have-local-offer', 'stable']);
+
+    return pc.createOffer()
+    .then(offer => pc.setLocalDescription(offer))
+    .then(() => {
+      assert_equals(pc.signalingState, 'have-local-offer');
+      assert_not_equals(pc.localDescription, null);
+      assert_not_equals(pc.pendingLocalDescription, null);
+      assert_equals(pc.currentLocalDescription, null);
+
+      return pc.setLocalDescription({ type: 'rollback' });
+    })
+    .then(() => {
+      assert_equals(pc.signalingState, 'stable');
+      assert_equals(pc.localDescription, null);
+      assert_equals(pc.pendingLocalDescription, null);
+      assert_equals(pc.currentLocalDescription, null);
+    });
+  }, 'setLocalDescription(rollback) from have-local-offer state should reset back to stable state');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setLocalDescription.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setLocalDescription.html
index be8ae58..d11936b 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setLocalDescription.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setLocalDescription.html
@@ -8,28 +8,80 @@
   'use strict';
 
   // Test is based on the following editor draft:
-  // https://w3c.github.io/webrtc-pc/archives/20170515/webrtc.html
+  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
 
   // The following helper functions are called from RTCPeerConnection-helper.js:
-  //   generateOffer()
-  //   generateAnswer()
-  //   assert_session_desc_not_equals()
-  //   assert_session_desc_equals()
-  //   test_state_change_event()
-  //   test_never_resolve()
-
+  //   generateOffer
+  //   generateAnswer
+  //   assert_session_desc_not_equals
+  //   assert_session_desc_equals
+  //   test_state_change_event
+  //   test_never_resolve
 
   /*
-   * 4.3.2. setLocalDescription(offer)
+    4.3.2.  Interface Definition
+      [Constructor(optional RTCConfiguration configuration)]
+      interface RTCPeerConnection : EventTarget {
+        Promise<void>                      setRemoteDescription(
+            RTCSessionDescriptionInit description);
+
+        readonly attribute RTCSessionDescription? remoteDescription;
+        readonly attribute RTCSessionDescription? currentRemoteDescription;
+        readonly attribute RTCSessionDescription? pendingRemoteDescription;
+        ...
+      };
+
+    4.6.2.  RTCSessionDescription Class
+      dictionary RTCSessionDescriptionInit {
+        required RTCSdpType type;
+                 DOMString  sdp = "";
+      };
+
+    4.6.1.  RTCSdpType
+      enum RTCSdpType {
+        "offer",
+        "pranswer",
+        "answer",
+        "rollback"
+      };
    */
 
   /*
-   *  5.  If description.sdp is null and description.type is offer, set description.sdp
-   *      to lastOffer.
+    4.3.2.  setLocalDescription
+      2.  Let lastOffer be the result returned by the last call to createOffer.
+      5.  If description.sdp is null and description.type is offer, set description.sdp
+          to lastOffer.
+
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.2.  If description is set as a local description, then run one of the following
+            steps:
+            - If description is of type "offer", set connection.pendingLocalDescription
+              to description and signaling state to have-local-offer.
    */
   promise_test(t => {
     const pc = new RTCPeerConnection();
-    return pc.createOffer()
+    test_state_change_event(t, pc, ['have-local-offer']);
+
+    return pc.createOffer({ offerToReceiveAudio: true })
+    .then(offer =>
+      pc.setLocalDescription(offer)
+      .then(() => {
+        assert_equals(pc.signalingState, 'have-local-offer');
+        assert_session_desc_equals(pc.localDescription, offer);
+        assert_session_desc_equals(pc.pendingLocalDescription, offer);
+        assert_equals(pc.currentLocalDescription, null);
+      }));
+  }, 'setLocalDescription with valid offer should succeed');
+
+  /*
+    4.3.2.  setLocalDescription
+      2.  Let lastOffer be the result returned by the last call to createOffer.
+      5.  If description.sdp is null and description.type is offer, set description.sdp
+          to lastOffer.
+   */
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+    return pc.createOffer({ offerToReceiveAudio: true })
     .then(offer =>
       pc.setLocalDescription({ type: 'offer' })
       .then(() => {
@@ -41,9 +93,11 @@
   }, 'setLocalDescription with type offer and null sdp should use lastOffer generated from createOffer');
 
   /*
-   *  6.  If description.type is offer and description.sdp does not match lastOffer,
-   *      reject the promise with a newly created InvalidModificationError and abort
-   *      these steps.
+    4.3.2.  setLocalDescription
+      2.  Let lastOffer be the result returned by the last call to createOffer.
+      6.  If description.type is offer and description.sdp does not match lastOffer,
+          reject the promise with a newly created InvalidModificationError and abort
+          these steps.
    */
   promise_test(t => {
     const pc = new RTCPeerConnection();
@@ -54,11 +108,6 @@
         pc.setLocalDescription(offer)));
   }, 'setLocalDescription() with offer not created by own createOffer() should reject with InvalidModificationError');
 
-  /*
-   *  6.  If description.type is offer and description.sdp does not match lastOffer,
-   *      reject the promise with a newly created InvalidModificationError and abort
-   *      these steps.
-   */
   promise_test(t => {
     // Create first offer with audio line, then second offer with
     // both audio and video line. Since the second offer is the
@@ -97,6 +146,10 @@
           }))));
   }, 'Creating and setting offer multiple times should succeed');
 
+  /*
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.2.1.  If connection's [[IsClosed]] slot is true, then abort these steps.
+   */
   test_never_resolve(t => {
     const pc = new RTCPeerConnection();
 
@@ -108,20 +161,24 @@
     });
   }, 'setLocalDescription(offer) should never resolve if connection is closed in parallel')
 
-  /*
-   *  TODO
-   *  4.3.1.  Setting an RTCSessionDescription
-   *    2.2.2.  If description is set as a local description, then run one of
-   *            the following steps:
-   *      - If description is of type "rollback", then this is a rollback. Set
-   *        connection.pendingLocalDescription to null and signaling state to stable.
-   *      - If description is of type "pranswer", then set connection.pendingLocalDescription
-   *        to description and signaling state to have-local-pranswer.
-   */
-
-
   /* setLocalDescription(answer) */
 
+
+  /*
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.  If description is set as a local description, then run one of the following
+          steps:
+
+        - If description is of type "answer", then this completes an offer answer
+          negotiation.
+
+          Set connection's currentLocalDescription to description and
+          currentRemoteDescription to the value of pendingRemoteDescription.
+
+          Set both pendingRemoteDescription and pendingLocalDescription to null.
+
+          Finally set connection's signaling state to stable.
+   */
   promise_test(t => {
     const pc = new RTCPeerConnection();
     test_state_change_event(t, pc, ['have-remote-offer', 'stable']);
@@ -145,6 +202,12 @@
         })));
   }, 'setLocalDescription() with valid answer should succeed');
 
+  /*
+    4.3.2.  setLocalDescription
+      3.  Let lastAnswer be the result returned by the last call to createAnswer.
+      4.  If description.sdp is null and description.type is answer, set description.sdp
+          to lastAnswer.
+   */
   promise_test(t => {
     const pc = new RTCPeerConnection();
 
@@ -167,6 +230,13 @@
         })));
   }, 'setLocalDescription() with type answer and null sdp should use lastAnswer generated from createAnswer');
 
+  /*
+    4.3.2.  setLocalDescription
+      3.  Let lastAnswer be the result returned by the last call to createAnswer.
+      7.  If description.type is answer and description.sdp does not match lastAnswer,
+          reject the promise with a newly created InvalidModificationError and abort these
+          steps.
+   */
   promise_test(t => {
     const pc = new RTCPeerConnection();
 
@@ -179,10 +249,7 @@
           pc.setLocalDescription(answer))));
   }, 'setLocalDescription() with answer not created by own createAnswer() should reject with InvalidModificationError');
 
-  /*
-   *  Operations after returning to stable state
-   */
-
+  /* Operations after returning to stable state */
   promise_test(t => {
     const pc = new RTCPeerConnection();
     test_state_change_event(t, pc, ['have-local-offer', 'stable', 'have-local-offer']);
@@ -230,16 +297,14 @@
   }, 'Switching role from answerer to offerer after going back to stable state should succeed');
 
   /*
-   *  InvalidStateError
-   *    [webrtc-pc] 4.3.1. Setting the RTCSessionDescription
-   *      2.3.  If the description's type is invalid for the current signaling state
-   *            of connection, then reject p with a newly created InvalidStateError
-   *            and abort these steps.
-   */
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.3.  If the description's type is invalid for the current signaling state of
+            connection, then reject p with a newly created InvalidStateError and abort
+            these steps.
 
-  /*
-   *  [jsep] 5.5. If the type is "pranswer" or "answer", the PeerConnection
-   *              state MUST be either "have-remote-offer" or "have-local-pranswer".
+    [jsep]
+      5.5. If the type is "pranswer" or "answer", the PeerConnection
+           state MUST be either "have-remote-offer" or "have-local-pranswer".
    */
   promise_test(t => {
     const pc = new RTCPeerConnection();
@@ -251,10 +316,6 @@
 
   }, 'Calling setLocalDescription(answer) from stable state should reject with InvalidStateError');
 
-  /*
-   *  [jsep] 5.5. If the type is "pranswer" or "answer", the PeerConnection
-   *              state MUST be either "have-remote-offer" or "have-local-pranswer".
-   */
   promise_test(t => {
     const pc = new RTCPeerConnection();
 
@@ -267,4 +328,14 @@
         pc.setLocalDescription(answer)));
   }, 'Calling setLocalDescription(answer) from have-local-offer state should reject with InvalidStateError');
 
+  /*
+    TODO
+      4.3.2.  setLocalDescription
+        4.  If description.sdp is null and description.type is pranswer, set description.sdp
+            to lastAnswer.
+        7.  If description.type is pranswer and description.sdp does not match lastAnswer,
+            reject the promise with a newly created InvalidModificationError and abort these
+            steps.
+   */
+
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-pranswer.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-pranswer.html
new file mode 100644
index 0000000..443178f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-pranswer.html
@@ -0,0 +1,150 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>RTCPeerConnection.prototype.setRemoteDescription pranswer</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="RTCPeerConnection-helper.js"></script>
+<script>
+  'use strict';
+
+  // Test is based on the following editor draft:
+  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
+
+  // The following helper functions are called from RTCPeerConnection-helper.js:
+  //   generateOffer
+  //   generateAnswer
+  //   assert_session_desc_equals
+  //   test_state_change_event
+
+  /*
+    4.3.2.  Interface Definition
+      [Constructor(optional RTCConfiguration configuration)]
+      interface RTCPeerConnection : EventTarget {
+        Promise<void>                      setLocalDescription(
+            RTCSessionDescriptionInit description);
+
+        readonly attribute RTCSessionDescription? localDescription;
+        readonly attribute RTCSessionDescription? currentLocalDescription;
+        readonly attribute RTCSessionDescription? pendingLocalDescription;
+
+        Promise<void>                      setRemoteDescription(
+            RTCSessionDescriptionInit description);
+
+        readonly attribute RTCSessionDescription? remoteDescription;
+        readonly attribute RTCSessionDescription? currentRemoteDescription;
+        readonly attribute RTCSessionDescription? pendingRemoteDescription;
+        ...
+      };
+
+    4.6.2.  RTCSessionDescription Class
+      dictionary RTCSessionDescriptionInit {
+        required RTCSdpType type;
+                 DOMString  sdp = "";
+      };
+
+    4.6.1.  RTCSdpType
+      enum RTCSdpType {
+        "offer",
+        "pranswer",
+        "answer",
+        "rollback"
+      };
+   */
+
+  /*
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.1.3.  If the description's type is invalid for the current signaling state of
+              connection, then reject p with a newly created InvalidStateError and abort
+              these steps.
+
+    [JSEP]
+      5.6.  If the type is "pranswer" or "answer", the PeerConnection state MUST be either
+            "have-local-offer" or "have-remote-pranswer".
+   */
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+
+    return generateOffer()
+    .then(offer =>
+      promise_rejects(t, 'InvalidStateError',
+        pc.setRemoteDescription({ type: 'pranswer', sdp: offer.sdp })));
+  }, 'setRemoteDescription(pranswer) from stable state should reject with InvalidStateError');
+
+  /*
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.2.3.  Otherwise, if description is set as a remote description, then run one
+              of the following steps:
+        - If description is of type "pranswer", then set
+          connection.pendingRemoteDescription to description and signaling state
+          to have-remote-pranswer.
+   */
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+    test_state_change_event(t, pc, ['have-local-offer', 'have-remote-pranswer']);
+
+    return pc.createOffer({ offerToReceiveVideo: true })
+    .then(offer =>
+      pc.setLocalDescription(offer)
+      .then(() => generateAnswer(offer))
+      .then(answer => {
+        const pranswer = { type: 'pranswer', sdp: answer.sdp };
+
+        return pc.setRemoteDescription(pranswer)
+        .then(() => {
+          assert_equals(pc.signalingState, 'have-remote-pranswer');
+
+          assert_session_desc_equals(pc.localDescription, offer);
+          assert_session_desc_equals(pc.pendingLocalDescription, offer);
+          assert_equals(pc.currentLocalDescription, null);
+
+          assert_session_desc_equals(pc.remoteDescription, pranswer);
+          assert_session_desc_equals(pc.pendingRemoteDescription, pranswer);
+          assert_equals(pc.currentRemoteDescription, null);
+        });
+      }));
+  }, 'setRemoteDescription(pranswer) from have-local-offer state should succeed');
+
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+    test_state_change_event(t, pc, ['have-local-offer', 'have-remote-pranswer']);
+
+    return pc.createOffer({ offerToReceiveVideo: true })
+    .then(offer =>
+      pc.setLocalDescription(offer)
+      .then(() => generateAnswer(offer))
+      .then(answer => {
+        const pranswer = { type: 'pranswer', sdp: answer.sdp };
+
+        return pc.setRemoteDescription(pranswer)
+        .then(() => pc.setRemoteDescription(pranswer));
+      }));
+  }, 'setRemoteDescription(pranswer) multiple times should succeed');
+
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+    test_state_change_event(t, pc, ['have-local-offer', 'have-remote-pranswer', 'stable']);
+
+    return pc.createOffer({ offerToReceiveVideo: true })
+    .then(offer =>
+      pc.setLocalDescription(offer)
+      .then(() => generateAnswer(offer))
+      .then(answer => {
+        const pranswer = { type: 'pranswer', sdp: answer.sdp };
+
+        return pc.setRemoteDescription(pranswer)
+        .then(() => pc.setRemoteDescription(answer))
+        .then(() => {
+          assert_equals(pc.signalingState, 'stable');
+
+          assert_session_desc_equals(pc.localDescription, offer);
+          assert_session_desc_equals(pc.currentLocalDescription, offer);
+          assert_equals(pc.pendingLocalDescription, null);
+
+          assert_session_desc_equals(pc.remoteDescription, answer);
+          assert_session_desc_equals(pc.currentRemoteDescription, answer);
+          assert_equals(pc.pendingRemoteDescription, null);
+        });
+      }));
+  }, 'setRemoteDescription(answer) from have-remote-pranswer state should succeed');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-rollback.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-rollback.html
new file mode 100644
index 0000000..31eea90
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription-rollback.html
@@ -0,0 +1,83 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>RTCPeerConnection.prototype.setRemoteDescription rollback</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="RTCPeerConnection-helper.js"></script>
+<script>
+  'use strict';
+
+  // Test is based on the following editor draft:
+  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
+
+  // The following helper functions are called from RTCPeerConnection-helper.js:
+  //   generateOffer
+  //   assert_session_desc_equals
+  //   test_state_change_event
+
+  /*
+    4.3.2.  Interface Definition
+      [Constructor(optional RTCConfiguration configuration)]
+      interface RTCPeerConnection : EventTarget {
+        Promise<void>                      setLocalDescription(
+            RTCSessionDescriptionInit description);
+
+        readonly attribute RTCSessionDescription? localDescription;
+        readonly attribute RTCSessionDescription? currentLocalDescription;
+        readonly attribute RTCSessionDescription? pendingLocalDescription;
+
+        Promise<void>                      setRemoteDescription(
+            RTCSessionDescriptionInit description);
+
+        readonly attribute RTCSessionDescription? remoteDescription;
+        readonly attribute RTCSessionDescription? currentRemoteDescription;
+        readonly attribute RTCSessionDescription? pendingRemoteDescription;
+        ...
+      };
+
+    4.6.2.  RTCSessionDescription Class
+      dictionary RTCSessionDescriptionInit {
+        required RTCSdpType type;
+                 DOMString  sdp = "";
+      };
+
+    4.6.1.  RTCSdpType
+      enum RTCSdpType {
+        "offer",
+        "pranswer",
+        "answer",
+        "rollback"
+      };
+   */
+
+  /*
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.2.3.  Otherwise, if description is set as a remote description, then run one
+              of the following steps:
+        - If description is of type "rollback", then this is a rollback.
+          Set connection.pendingRemoteDescription to null and signaling state to stable.
+   */
+  promise_test(t => {
+    const pc = new RTCPeerConnection();
+
+    test_state_change_event(t, pc, ['have-remote-offer', 'stable']);
+
+    return generateOffer({ data: true })
+    .then(offer => pc.setRemoteDescription(offer))
+    .then(() => {
+      assert_equals(pc.signalingState, 'have-remote-offer');
+      assert_not_equals(pc.remoteDescription, null);
+      assert_not_equals(pc.pendingRemoteDescription, null);
+      assert_equals(pc.currentRemoteDescription, null);
+
+      return pc.setRemoteDescription({ type: 'rollback' });
+    })
+    .then(() => {
+      assert_equals(pc.signalingState, 'stable');
+      assert_equals(pc.remoteDescription, null);
+      assert_equals(pc.pendingRemoteDescription, null);
+      assert_equals(pc.currentRemoteDescription, null);
+    });
+  }, 'setRemoteDescription(rollback) in have-remote-offer state should revert to stable state');
+
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription.html
index da1f488e..50a719d5 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCPeerConnection-setRemoteDescription.html
@@ -8,7 +8,7 @@
   'use strict';
 
   // Test is based on the following editor draft:
-  // https://w3c.github.io/webrtc-pc/archives/20170515/webrtc.html
+  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
 
   // The following helper functions are called from RTCPeerConnection-helper.js:
   //   generateOffer()
@@ -19,9 +19,40 @@
   //   test_never_resolve()
 
   /*
-   *  4.3.2.  setRemoteDescription(offer)
+    4.3.2.  Interface Definition
+      [Constructor(optional RTCConfiguration configuration)]
+      interface RTCPeerConnection : EventTarget {
+        Promise<void>                      setRemoteDescription(
+            RTCSessionDescriptionInit description);
+
+        readonly attribute RTCSessionDescription? remoteDescription;
+        readonly attribute RTCSessionDescription? currentRemoteDescription;
+        readonly attribute RTCSessionDescription? pendingRemoteDescription;
+        ...
+      };
+
+    4.6.2.  RTCSessionDescription Class
+      dictionary RTCSessionDescriptionInit {
+        required RTCSdpType type;
+                 DOMString  sdp = "";
+      };
+
+    4.6.1.  RTCSdpType
+      enum RTCSdpType {
+        "offer",
+        "pranswer",
+        "answer",
+        "rollback"
+      };
    */
 
+  /*
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.2.3.  Otherwise, if description is set as a remote description, then run one of
+              the following steps:
+        - If description is of type "offer", set connection.pendingRemoteDescription
+          attribute to description and signaling state to have-remote-offer.
+   */
   promise_test(t => {
     const pc = new RTCPeerConnection();
 
@@ -58,6 +89,10 @@
       }));
   }, 'Setting remote description multiple times with different offer should succeed');
 
+  /*
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.2.1.  If connection's [[IsClosed]] slot is true, then abort these steps.
+   */
   test_never_resolve(t => {
     const pc = new RTCPeerConnection();
 
@@ -70,11 +105,11 @@
   }, 'setRemoteDescription(offer) should never resolve if connection is closed in parallel')
 
   /*
-   *  4.3.1.  Setting an RTCSessionDescription
-   *    2.4.  If the content of description is not valid SDP syntax, then reject p
-   *          with an RTCError (with errorDetail set to "sdp-syntax-error" and the
-   *          sdpLineNumber attribute set to the line number in the SDP where the
-   *          syntax error was detected) and abort these steps.
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.1.4.  If the content of description is not valid SDP syntax, then reject p with
+              an RTCError (with errorDetail set to "sdp-syntax-error" and the
+              sdpLineNumber attribute set to the line number in the SDP where the syntax
+              error was detected) and abort these steps.
    */
   promise_test(t => {
     const pc = new RTCPeerConnection();
@@ -95,7 +130,7 @@
   }, 'setRemoteDescription(offer) with invalid SDP should reject with RTCError');
 
   /*
-   *  4.6.1.  enum RTCSdpType
+    4.6.1.  enum RTCSdpType
    */
   promise_test(t => {
     const pc = new RTCPeerConnection();
@@ -119,25 +154,22 @@
       }));
   }, 'setRemoteDescription() with invalid SDP and stable state should reject with InvalidStateError')
 
-  /*
-   *  TODO
-   *  Setting an RTCSessionDescription
-   *    2.1.5. If the content of description is invalid, then reject p with
-   *       a newly created InvalidAccessError and abort these steps.
-   *    2.2.5-10
-   *  setRemoteDescription(rollback)
-   *  setRemoteDescription(pranswer)
-   *
-   *  Non-testable
-   *  Setting an RTCSessionDescription
-   *    6. For all other errors, for example if description cannot be
-   *       applied at the media layer, reject p with a newly created OperationError.
-   */
+  /* setRemoteDescription(answer) */
 
   /*
-   *  4.3.2.  setRemoteDescription(answer)
-   */
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.2.3.  Otherwise, if description is set as a remote description, then run one of
+              the following steps:
+        - If description is of type "answer", then this completes an offer answer
+          negotiation.
 
+          Set connection's currentRemoteDescription to description and
+          currentLocalDescription to the value of pendingLocalDescription.
+
+          Set both pendingRemoteDescription and pendingLocalDescription to null.
+
+          Finally setconnection's signaling state to stable.
+   */
   promise_test(t => {
     const pc = new RTCPeerConnection();
     test_state_change_event(t, pc, ['have-local-offer', 'stable']);
@@ -149,6 +181,8 @@
       .then(answer =>
         pc.setRemoteDescription(answer)
         .then(() => {
+          assert_equals(pc.signalingState, 'stable');
+
           assert_session_desc_equals(pc.localDescription, offer);
           assert_session_desc_equals(pc.remoteDescription, answer);
 
@@ -160,28 +194,7 @@
         })));
   }, 'setRemoteDescription() with valid state and answer should succeed');
 
-  /*
-   *  TODO
-   *  4.3.2 setRemoteDescription
-   *    If an a=identity attribute is present in the session description,
-   *    the browser validates the identity assertion.
-   *
-   *    If the "peerIdentity" configuration is applied to the RTCPeerConnection,
-   *    this establishes a target peer identity of the provided value. Alternatively,
-   *    if the RTCPeerConnection has previously authenticated the identity of the
-   *    peer (that is, there is a current value for peerIdentity ), then this also
-   *    establishes a target peer identity.
-   *
-   *    The target peer identity cannot be changed once set. Once set,
-   *    if a different value is provided, the user agent must reject
-   *    the returned promise with a newly created InvalidModificationError
-   *    and abort this operation. The RTCPeerConnection must be closed if
-   *    the validated peer identity does not match the target peer identity.
-   */
-
-  /*
-   *  Operations after returning to stable state
-   */
+  /* Operations after returning to stable state */
 
   promise_test(t => {
     const pc = new RTCPeerConnection();
@@ -231,16 +244,14 @@
   }, 'Switching role from offerer to answerer after going back to stable state should succeed');
 
   /*
-   *  InvalidStateError
-   *    [webrtc-pc] 4.3.1. Setting the RTCSessionDescription
-   *      2.3.  If the description's type is invalid for the current signaling state
-   *            of connection, then reject p with a newly created InvalidStateError
-   *            and abort these steps.
-   */
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.1.3.  If the description's type is invalid for the current signaling state of
+              connection, then reject p with a newly created InvalidStateError and abort
+              these steps.
 
-  /*
-   *  [jsep] 5.6. If the type is "pranswer" or "answer", the PeerConnection
-   *              state MUST be either "have-local-offer" or "have-remote-pranswer".
+    [JSEP]
+      5.6.  If the type is "answer", the PeerConnection state MUST be either
+            "have-local-offer" or "have-remote-pranswer".
    */
   promise_test(t => {
     const pc = new RTCPeerConnection();
@@ -251,26 +262,6 @@
         pc.setRemoteDescription({ type: 'answer', sdp: offer.sdp })));
   }, 'Calling setRemoteDescription(answer) from stable state should reject with InvalidStateError');
 
-
-  /*
-   *  [jsep] 5.6. If the type is "offer", the PeerConnection state
-   *              MUST be either "stable" or "have-remote-offer".
-   */
-  promise_test(t => {
-    const pc = new RTCPeerConnection();
-
-    return pc.createOffer()
-    .then(offer => pc.setLocalDescription(offer))
-    .then(() => generateOffer())
-    .then(offer =>
-      promise_rejects(t, 'InvalidStateError',
-        pc.setRemoteDescription(offer)));
-  }, 'Calling setRemoteDescription(offer) from have-local-offer state should reject with InvalidStateError');
-
-  /*
-   *  [jsep] 5.6. If the type is "pranswer" or "answer", the PeerConnection
-   *              state MUST be either "have-local-offer" or "have-remote-pranswer".
-   */
   promise_test(t => {
     const pc = new RTCPeerConnection();
 
@@ -284,44 +275,32 @@
 
   }, 'Calling setRemoteDescription(answer) from have-remote-offer state should reject with InvalidStateError');
 
-  // tests that ontrack is called and parses the msid information from the SDP and creates
-  // the streams with matching identifiers.
-  async_test(t => {
+  /*
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.1.3.  If the description's type is invalid for the current signaling state of
+              connection, then reject p with a newly created InvalidStateError and abort
+              these steps.
+
+    [JSEP]
+      5.6.  If the type is "offer", the PeerConnection state MUST be either "stable" or
+            "have-remote-offer".
+   */
+  promise_test(t => {
     const pc = new RTCPeerConnection();
 
-    // Fail the test if the ontrack event handler is not implemented
-    assert_own_property(pc, 'ontrack', 'Expect pc to have ontrack event handler attribute');
+    return pc.createOffer()
+    .then(offer => pc.setLocalDescription(offer))
+    .then(() => generateOffer())
+    .then(offer =>
+      promise_rejects(t, 'InvalidStateError',
+        pc.setRemoteDescription(offer)));
+  }, 'Calling setRemoteDescription(offer) from have-local-offer state should reject with InvalidStateError');
 
-    const sdp = `v=0
-o=- 166855176514521964 2 IN IP4 127.0.0.1
-s=-
-t=0 0
-a=msid-semantic:WMS *
-m=audio 9 UDP/TLS/RTP/SAVPF 111
-c=IN IP4 0.0.0.0
-a=rtcp:9 IN IP4 0.0.0.0
-a=ice-ufrag:someufrag
-a=ice-pwd:somelongpwdwithenoughrandomness
-a=fingerprint:sha-256 8C:71:B3:8D:A5:38:FD:8F:A4:2E:A2:65:6C:86:52:BC:E0:6E:94:F2:9F:7C:4D:B5:DF:AF:AA:6F:44:90:8D:F4
-a=setup:actpass
-a=rtcp-mux
-a=mid:mid1
-a=sendonly
-a=rtpmap:111 opus/48000/2
-a=msid:stream1 track1
-a=ssrc:1001 cname:some
-`;
-
-    pc.ontrack = t.step_func(event => {
-      assert_equals(event.streams.length, 1, 'the track belongs to one MediaStream');
-      assert_equals(event.streams[0].id, 'stream1', 'the stream name is parsed from the MSID line');
-      t.done();
-    });
-
-    pc.setRemoteDescription(new RTCSessionDescription({type: 'offer', sdp: sdp}))
-    .catch(t.step_func(err => {
-      assert_unreached('Error ' + err.name + ': ' + err.message);
-    }));
-  }, 'setRemoteDescription should trigger ontrack event when the MSID of the stream is is parsed.');
+  /*
+    TODO
+    4.3.2.  setRemoteDescription
+      - If an a=identity attribute is present in the session description, the browser
+        validates the identity assertion.
+   */
 
 </script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCSctpTransport-constructor.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCSctpTransport-constructor.html
index f840f1e..16b11e3 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCSctpTransport-constructor.html
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCSctpTransport-constructor.html
@@ -8,7 +8,7 @@
   'use strict';
 
   // Test is based on the following editor draft:
-  // https://w3c.github.io/webrtc-pc/archives/20170515/webrtc.html
+  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
 
   // The following helper functions are called from RTCPeerConnection-helper.js:
   //   generateOffer()
@@ -27,18 +27,16 @@
           readonly attribute unsigned long    maxMessageSize;
         };
 
-    4.3.1.  Operation
-      When the RTCPeerConnection() constructor is invoked
-        8.  Let connection have an [[sctpTransport]] internal slot,
-            initialized to null.
+    4.4.1.1.  Constructor
+      8.  Let connection have an [[sctpTransport]] internal slot, initialized to null.
 
-      To set an RTCSessionDescription description
-      6.  If description is of type "answer" or "pranswer", then run the
-          following steps:
-        1.  If description initiates the establishment of a new SCTP
-            association, as defined in [SCTP-SDP], Sections 10.3 and 10.4,
-            set the value of connection's [[sctpTransport]] internal slot
-            to a newly created RTCSctpTransport.
+    4.3.1.6.  Set the RTCSessionSessionDescription
+      2.2.6.  If description is of type "answer" or "pranswer", then run the
+              following steps:
+        1.  If description initiates the establishment of a new SCTP association,
+            as defined in [SCTP-SDP], Sections 10.3 and 10.4, set the value of
+            connection's [[SctpTransport]] internal slot to a newly created
+            RTCSctpTransport.
    */
 
   promise_test(t => {
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCTrackEvent-constructor-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCTrackEvent-constructor-expected.txt
new file mode 100644
index 0000000..ee38320
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCTrackEvent-constructor-expected.txt
@@ -0,0 +1,10 @@
+This is a testharness.js-based test.
+FAIL new RTCTrackEvent() with valid receiver, track, transceiver should succeed pc.addTransceiver is not a function
+FAIL new RTCTrackEvent() with valid receiver, track, streams, transceiver should succeed pc.addTransceiver is not a function
+FAIL new RTCTrackEvent() with valid receiver, track, multiple streams, transceiver should succeed pc.addTransceiver is not a function
+FAIL new RTCTrackEvent() with unrelated receiver, track, streams, transceiver should succeed pc.addTransceiver is not a function
+FAIL new RTCTrackEvent() with no transceiver should throw TypeError pc.addTransceiver is not a function
+FAIL new RTCTrackEvent() with no track should throw TypeError pc.addTransceiver is not a function
+FAIL new RTCTrackEvent() with no receiver should throw TypeError pc.addTransceiver is not a function
+Harness: the test ran to completion.
+
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCTrackEvent-constructor.html b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCTrackEvent-constructor.html
new file mode 100644
index 0000000..7948442
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/RTCTrackEvent-constructor.html
@@ -0,0 +1,158 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>RTCTrackEvent constructor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+  'use strict';
+
+  // Test is based on the following editor draft:
+  // https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
+
+  /*
+    5.7.  RTCTrackEvent
+      [Constructor(DOMString type, RTCTrackEventInit eventInitDict)]
+      interface RTCTrackEvent : Event {
+        readonly attribute RTCRtpReceiver           receiver;
+        readonly attribute MediaStreamTrack         track;
+        [SameObject]
+        readonly attribute FrozenArray<MediaStream> streams;
+        readonly attribute RTCRtpTransceiver        transceiver;
+      };
+
+      dictionary RTCTrackEventInit : EventInit {
+        required RTCRtpReceiver        receiver;
+        required MediaStreamTrack      track;
+                 sequence<MediaStream> streams = [];
+        required RTCRtpTransceiver     transceiver;
+      };
+   */
+
+  test(t => {
+    const pc = new RTCPeerConnection();
+    const transceiver = pc.addTransceiver('audio');
+    const { receiver } = transceiver;
+    const { track } = receiver;
+
+    const trackEvent = new RTCTrackEvent('track', {
+      receiver, track, transceiver
+    });
+
+    assert_equals(trackEvent.receiver, receiver);
+    assert_equals(trackEvent.track, track);
+    assert_array_equals(trackEvent.streams, []);
+    assert_equals(trackEvent.transceiver, transceiver);
+
+    assert_equals(event.type, 'track');
+    assert_false(event.bubbles);
+    assert_false(event.cancelable);
+
+  }, `new RTCTrackEvent() with valid receiver, track, transceiver should succeed`);
+
+  test(t => {
+    const pc = new RTCPeerConnection();
+    const transceiver = pc.addTransceiver('audio');
+    const { receiver } = transceiver;
+    const { track } = receiver;
+
+    const stream = new MediaStream([track]);
+
+    const trackEvent = new RTCTrackEvent('track', {
+      receiver, track, transceiver,
+      streams: [stream]
+    });
+
+    assert_equals(trackEvent.receiver, receiver);
+    assert_equals(trackEvent.track, track);
+    assert_array_equals(trackEvent.streams, [stream]);
+    assert_equals(trackEvent.transceiver, transceiver);
+
+  }, `new RTCTrackEvent() with valid receiver, track, streams, transceiver should succeed`);
+
+  test(t => {
+    const pc = new RTCPeerConnection();
+    const transceiver = pc.addTransceiver('audio');
+    const { receiver } = transceiver;
+    const { track } = receiver;
+
+    const stream1 = new MediaStream([track]);
+    const stream2 = new MediaStream([track]);
+
+    const trackEvent = new RTCTrackEvent('track', {
+      receiver, track, transceiver,
+      streams: [stream1, stream2]
+    });
+
+    assert_equals(trackEvent.receiver, receiver);
+    assert_equals(trackEvent.track, track);
+    assert_array_equals(trackEvent.streams, [stream1, stream2]);
+    assert_equals(trackEvent.transceiver, transceiver);
+
+  }, `new RTCTrackEvent() with valid receiver, track, multiple streams, transceiver should succeed`);
+
+  test(t => {
+    const pc = new RTCPeerConnection();
+    const transceiver = pc.addTransceiver('audio');
+    const receiver = pc.addTransceiver('audio').receiver;
+    const track =  pc.addTransceiver('audio').receiver.track;
+
+    const stream = new MediaStream();
+
+    const trackEvent = new RTCTrackEvent('track', {
+      receiver, track, transceiver,
+      streams: [stream]
+    });
+
+    assert_equals(trackEvent.receiver, receiver);
+    assert_equals(trackEvent.track, track);
+    assert_array_equals(trackEvent.streams, [stream]);
+    assert_equals(trackEvent.transceiver, transceiver);
+
+  }, `new RTCTrackEvent() with unrelated receiver, track, streams, transceiver should succeed`);
+
+  test(t => {
+    const pc = new RTCPeerConnection();
+    const transceiver = pc.addTransceiver('audio');
+    const { receiver } = transceiver;
+    const { track } = receiver;
+
+    assert_throws(new TypeError(), () =>
+      new RTCTrackEvent('track', {
+        receiver, track
+      }));
+
+  }, `new RTCTrackEvent() with no transceiver should throw TypeError`);
+
+  test(t => {
+    const pc = new RTCPeerConnection();
+    const transceiver = pc.addTransceiver('audio');
+    const { receiver } = transceiver;
+
+    assert_throws(new TypeError(), () =>
+      new RTCTrackEvent('track', {
+        receiver, transceiver
+      }));
+
+  }, `new RTCTrackEvent() with no track should throw TypeError`);
+
+  test(t => {
+    const pc = new RTCPeerConnection();
+    const transceiver = pc.addTransceiver('audio');
+    const { receiver } = transceiver;
+    const { track } = receiver;
+
+    assert_throws(new TypeError(), () =>
+      new RTCTrackEvent('track', {
+        track, transceiver
+      }));
+
+  }, `new RTCTrackEvent() with no receiver should throw TypeError`);
+
+  /*
+    Coverage Report
+      Interface tests are counted as 1 trivial test
+
+      Tested         1
+      Total          1
+   */
+</script>
diff --git a/third_party/WebKit/LayoutTests/external/wpt/webrtc/coverage/set-session-description.txt b/third_party/WebKit/LayoutTests/external/wpt/webrtc/coverage/set-session-description.txt
new file mode 100644
index 0000000..1071778
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/external/wpt/webrtc/coverage/set-session-description.txt
@@ -0,0 +1,242 @@
+Coverage Report is based on the following editor draft:
+https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
+
+4.3.1.6 Set the RTCSessionSessionDescription
+
+  [Trivial]
+  1.  Let p be a new promise.
+
+  [Trivial]
+  2.  In parallel, start the process to apply description as described in [JSEP]
+      (section 5.5. and section 5.6.).
+
+    [Trivial]
+    1.  If the process to apply description fails for any reason, then user agent
+        MUST queue a task that runs the following steps:
+
+      [RTCPeerConnection-setLocalDescription]
+      [RTCPeerConnection-setRemoteDescription]
+      1.  If connection's [[IsClosed]] slot is true, then abort these steps.
+
+      [Untestable]
+      2.  If elements of the SDP were modified, then reject p with a newly created
+          InvalidModificationError and abort these steps.
+
+      [RTCPeerConnection-setLocalDescription]
+      [RTCPeerConnection-setRemoteDescription]
+      3.  If the description's type is invalid for the current signaling state of
+          connection as described in [JSEP] (section 5.5. and section 5.6.), then
+          reject p with a newly created InvalidStateError and abort these steps.
+
+      [RTCPeerConnection-setLocalDescription]
+      [RTCPeerConnection-setRemoteDescription]
+      4.  If the content of description is not valid SDP syntax, then reject p
+          with an RTCError (with errorDetail set to "sdp-syntax-error" and the
+          sdpLineNumber attribute set to the line number in the SDP where the
+          syntax error was detected) and abort these steps.
+
+      [Untestable]
+      5.  If the content of description is invalid, then reject p with a newly
+          created InvalidAccessError and abort these steps.
+
+      [Untestable]
+      6.  For all other errors, for example if description cannot be applied at
+          the media layer, reject p with a newly created OperationError.
+
+    [Trivial]
+    2.  If description is applied successfully, the user agent MUST queue a task
+        that runs the following steps:
+
+      [RTCPeerConnection-setLocalDescription]
+      [RTCPeerConnection-setRemoteDescription]
+      1.  If connection's [[isClosed]] slot is true, then abort these steps.
+
+      [RTCPeerConnection-setLocalDescription]
+      2.  If description is set as a local description, then run one of the
+          following steps:
+
+        [RTCPeerConnection-setLocalDescription]
+        - If description is of type "offer", set connection.pendingLocalDescription
+          to description and signaling state to have-local-offer.
+
+        [RTCPeerConnection-setLocalDescription]
+        - If description is of type "answer", then this completes an offer answer
+          negotiation.
+
+          Set connection's currentLocalDescription to description and
+          currentRemoteDescription to the value of pendingRemoteDescription.
+
+          Set both pendingRemoteDescription and pendingLocalDescription to null.
+          Finally set connection's signaling state to stable
+
+        [TODO setLocalDescription]
+        - If description is of type "rollback", then this is a rollback. Set
+          connection.pendingLocalDescription to null and signaling state to stable.
+
+        [TODO setLocalDescription]
+        - If description is of type "pranswer", then set
+          connection.pendingLocalDescription to description and signaling state to
+          have-local-pranswer.
+
+    [RTCPeerConnection-setRemoteDescription]
+    3.  Otherwise, if description is set as a remote description, then run one of the
+        following steps:
+
+      [RTCPeerConnection-setRemoteDescription]
+      - If description is of type "offer", set connection.pendingRemoteDescription
+        attribute to description and signaling state to have-remote-offer.
+
+      [RTCPeerConnection-setRemoteDescription]
+      - If description is of type "answer", then this completes an offer answer
+        negotiation.
+
+        Set connection's currentRemoteDescription to description and
+        currentLocalDescription to the value of pendingLocalDescription.
+
+        Set both pendingRemoteDescription and pendingLocalDescription to null.
+
+        Finally setconnection's signaling state to stable
+
+      [TODO setRemoteDescription]
+      - If description is of type "rollback", then this is a rollback.
+        Set connection.pendingRemoteDescription to null and signaling state to stable.
+
+      [TODO setRemoteDescription]
+      - If description is of type "pranswer", then set
+        connection.pendingRemoteDescription to description and signaling state
+        to have-remote-pranswer.
+
+    [RTCPeerConnection-setLocalDescription]
+    [RTCPeerConnection-setRemoteDescription]
+    4.  If connection's signaling state changed above, fire a simple event named
+        signalingstatechange at connection.
+
+    [TODO]
+    5.  If description is of type "answer", and it initiates the closure of an existing
+        SCTP association, as defined in [SCTP-SDP], Sections 10.3 and 10.4, set the value
+        of connection's [[sctpTransport]] internal slot to null.
+
+    [RTCSctpTransport]
+    6.  If description is of type "answer" or "pranswer", then run the following steps:
+
+      [RTCSctpTransport]
+      1.  If description initiates the establishment of a new SCTP association,
+          as defined in [SCTP-SDP], Sections 10.3 and 10.4, set the value of connection's
+          [[sctpTransport]] internal slot to a newly created RTCSctpTransport.
+
+      [TODO]
+      2.  If description negotiates the DTLS role of the SCTP transport, and there is an
+          RTCDataChannel with a null id, then generate an ID according to
+          [RTCWEB-DATA-PROTOCOL].
+
+          [Untestable]
+          If no available ID could be generated, then run the following steps:
+
+            [Untestable]
+            1.  Let channel be the RTCDataChannel object for which an ID could not be
+                generated.
+
+            [Untestable]
+            2.  Set channel's readyState attribute to closed.
+
+            [Untestable]
+            3.  Fire an event named error with a ResourceInUse exception at channel.
+
+            [Untestable]
+            4.  Fire a simple event named close at channel.
+
+    [TODO]
+    7.  If description is set as a local description, then run the following steps for
+        each media description in description that is not yet associated with an
+        RTCRtpTransceiver object:
+
+      [TODO]
+      1.  Let transceiver be the RTCRtpTransceiver used to create the media
+          description.
+
+      [TODO]
+      2.  Set transceiver's mid value to the mid of the corresponding media
+          description.
+
+    [TODO]
+    8.  If description is set as a remote description, then run the following steps
+        for each media description in description:
+
+      [TODO]
+      1.  As described by [JSEP] (section 5.9.), attempt to find an existing
+          RTCRtpTransceiver object, transceiver, to represent the media description.
+
+      [TODO]
+      2.  If no suitable transceiver is found (transceiver is unset), run the following
+          steps:
+
+        [TODO]
+        1.  Create an RTCRtpSender, sender, from the media description.
+
+        [TODO]
+        2.  Create an RTCRtpReceiver, receiver, from the media description.
+
+        [TODO]
+        3.  Create an RTCRtpTransceiver with sender, receiver and direction, and let
+            transceiver be the result.
+
+      [TODO]
+      3.  Set transceiver's mid value to the mid of the corresponding media description.
+          If the media description has no MID, and transceiver's mid is unset, generate
+          a random value as described in [JSEP] (section 5.9.).
+
+      [TODO]
+      4.  If the direction of the media description is sendrecv or sendonly, and
+          transceiver.receiver.track has not yet been fired in a track event, process
+          the remote track for the media description, given transceiver.
+
+      [TODO]
+      5.  If the media description is rejected, and transceiver is not already stopped,
+          stop the RTCRtpTransceiver transceiver.
+
+
+    [TODO]
+    9.  If description is of type "rollback", then run the following steps:
+
+      [TODO]
+      1.  If the mid value of an RTCRtpTransceiver was set to a non-null value by
+          the RTCSessionDescription that is being rolled back, set the mid value
+          of that transceiver to null, as described by [JSEP] (section 4.1.8.2.).
+
+      [TODO]
+      2.  If an RTCRtpTransceiver was created by applying the RTCSessionDescription
+          that is being rolled back, and a track has not been attached to it via
+          addTrack, remove that transceiver from connection's set of transceivers,
+          as described by [JSEP] (section 4.1.8.2.).
+
+      [TODO]
+      3.  Restore the value of connection's [[SctpTransport]] internal slot to its
+          value at the last stable signaling state.
+
+    [RTCPeerConnection-onnegotiationneeded]
+    10. If connection's signaling state is now stable, update the negotiation-needed
+            flag. If connection's [[NegotiationNeeded]] slot was true both before and after
+            this update, queue a task that runs the following steps:
+
+      [RTCPeerConnection-onnegotiationneeded]
+      1.  If connection's [[IsClosed]] slot is true, abort these steps.
+
+      [RTCPeerConnection-onnegotiationneeded]
+      2.  If connection's [[NegotiationNeeded]] slot is false, abort these steps.
+
+      [RTCPeerConnection-onnegotiationneeded]
+      3.  Fire a simple event named negotiationneeded at connection.
+
+    [Trivial]
+    11. Resolve p with undefined.
+
+  [Trivial]
+  3.  Return p.
+
+
+Coverage Report
+
+  Tested        28
+  Not Tested    22
+  Untestable     8
+  Total         58
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/background-repeat-with-background-color-expected.png b/third_party/WebKit/LayoutTests/fast/backgrounds/background-repeat-with-background-color-expected.png
deleted file mode 100644
index d0aeead..0000000
--- a/third_party/WebKit/LayoutTests/fast/backgrounds/background-repeat-with-background-color-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/background-svg-scaling-expected.png b/third_party/WebKit/LayoutTests/fast/backgrounds/background-svg-scaling-expected.png
deleted file mode 100644
index 3a7ef208..0000000
--- a/third_party/WebKit/LayoutTests/fast/backgrounds/background-svg-scaling-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/mask-box-image-expected.png b/third_party/WebKit/LayoutTests/fast/backgrounds/mask-box-image-expected.png
index e8c9508..d8e89b31 100644
--- a/third_party/WebKit/LayoutTests/fast/backgrounds/mask-box-image-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/backgrounds/mask-box-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize03-expected.png b/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize03-expected.png
index e3814e6..00e2e81 100644
--- a/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize03-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize03-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize15-expected.png b/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize15-expected.png
deleted file mode 100644
index 5d622cb..0000000
--- a/third_party/WebKit/LayoutTests/fast/backgrounds/size/backgroundSize15-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-both-expected.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-both-expected.html
deleted file mode 100644
index b6ea69a..0000000
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-both-expected.html
+++ /dev/null
@@ -1,129 +0,0 @@
-<!-- Based on FF test originally written by Ethan Lin.
-Changed it to force repeating the border image twice.
-Original can be found in:
-https://hg.mozilla.org/mozilla-central/raw-file/tip/layout/reftests/w3c-css/submitted/background/
--->
-<style type="text/css">
-   .outer {
-      width: 108px;
-      height: 108px;
-   }
-   .inner1 {
-      position: absolute;
-      top: 0px;
-      left: 0px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-   }
-   .inner2 {
-      position: absolute;
-      top: 0px;
-      left: 27px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: -27px 0px;
-   }
-   .inner22 {
-      position: absolute;
-      top: 0px;
-      left: 54px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: -27px 0px;
-   }
-   .inner3 {
-      position: absolute;
-      top: 0px;
-      left: 81px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-   }
-   .inner4 {
-      position: absolute;
-      top: 27px;
-      left: 0px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: 0px -27px;
-   }
-   .inner44 {
-      position: absolute;
-      top: 54px;
-      left: 0px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: 0px -27px;
-   }
-   .inner5 {
-      position: absolute;
-      top: 27px;
-      left: 81px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: -54px -27px;
-   }
-   .inner55 {
-      position: absolute;
-      top: 54px;
-      left: 81px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: -54px -27px;
-   }
-   .inner6 {
-      position: absolute;
-      top: 81px;
-      left: 0px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-   }
-   .inner7 {
-      position: absolute;
-      top: 81px;
-      left: 27px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: -27px -54px;
-   }
-   .inner77 {
-      position: absolute;
-      top: 81px;
-      left: 54px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: -27px -54px;
-   }
-   .inner8 {
-      position: absolute;
-      top: 81px;
-      left: 81px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-   }
-</style>
-<div class="outer">
-   <div class="inner1"></div>
-   <div class="inner2"></div>
-   <div class="inner22"></div>
-   <div class="inner3"></div>
-   <div class="inner4"></div>
-   <div class="inner5"></div>
-   <div class="inner44"></div>
-   <div class="inner55"></div>
-   <div class="inner6"></div>
-   <div class="inner7"></div>
-   <div class="inner77"></div>
-   <div class="inner8"></div>
-</div>
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-both-expected.png b/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-both-expected.png
new file mode 100644
index 0000000..9959ce8f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-both-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-horiz-expected.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-horiz-expected.html
deleted file mode 100644
index 3ac39a3d..0000000
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-horiz-expected.html
+++ /dev/null
@@ -1,111 +0,0 @@
-<!-- Based on FF test originally written by Ethan Lin.
-Changed it to force repeating the border image twice along x.
-Original can be found in:
-https://hg.mozilla.org/mozilla-central/raw-file/tip/layout/reftests/w3c-css/submitted/background/
--->
-<style type="text/css">
-   .outer {
-      width: 108px;
-      height: 108px;
-  }
-
-    .inner1 {
-      position: absolute;
-      top: 0px;
-      left: 0px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-  }
-   .inner2 {
-      position: absolute;
-      top: 0px;
-      left: 27px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: -27px 0px;
-  }
-   .inner22 {
-      position: absolute;
-      top: 0px;
-      left: 54px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: -27px 0px;
-  }
-   .inner3 {
-      position: absolute;
-      top: 0px;
-      left: 81px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-  }
-   .inner4 {
-      position: absolute;
-      top: 27px;
-      left: 0px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: 0px -27px;
-  }
-   .inner5 {
-      position: absolute;
-      top: 27px;
-      left: 81px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: -54px -27px;
-  }
-   .inner6 {
-      position: absolute;
-      top: 54px;
-      left: 0px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-  }
-   .inner7 {
-      position: absolute;
-      top: 54px;
-      left: 27px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: -27px -54px;
-  }
-   .inner77 {
-      position: absolute;
-      top: 54px;
-      left: 54px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: -27px -54px;
-  }
-   .inner8 {
-      position: absolute;
-      top: 54px;
-      left: 81px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-  }
-</style>
-
-<div class="outer">
-   <div class="inner1"></div>
-   <div class="inner2"></div>
-   <div class="inner22"></div>
-   <div class="inner3"></div>
-   <div class="inner4"></div>
-   <div class="inner5"></div>
-   <div class="inner6"></div>
-   <div class="inner7"></div>
-   <div class="inner77"></div>
-   <div class="inner8"></div>
-</div>
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-horiz-expected.png b/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-horiz-expected.png
new file mode 100644
index 0000000..486b05f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-horiz-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-non-multiple-expected.html b/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-non-multiple-expected.html
deleted file mode 100644
index a7a89c0..0000000
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-non-multiple-expected.html
+++ /dev/null
@@ -1,91 +0,0 @@
-<!-- Based on FF test originally written by Ethan Lin.
-Changed it to have a single image positioned in the middle
-of element side.
-Original can be found in:
-https://hg.mozilla.org/mozilla-central/raw-file/tip/layout/reftests/w3c-css/submitted/background/
--->
-<style type="text/css">
-   .outer {
-      width: 94px;
-      height: 94px;
-   }
-   .inner1 {
-      position: absolute;
-      top: 0px;
-      left: 0px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-   }
-   .inner2 {
-      position: absolute;
-      top: 0px;
-      left: 33px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: -27px 0px;
-   }
-   .inner3 {
-      position: absolute;
-      top: 0px;
-      left: 66px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-   }
-   .inner4 {
-      position: absolute;
-      top: 33px;
-      left: 0px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: 0px -27px;
-   }
-   .inner5 {
-      position: absolute;
-      top: 33px;
-      left: 66px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: -54px -27px;
-   }
-   .inner6 {
-      position: absolute;
-      top: 66px;
-      left: 0px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-   }
-   .inner7 {
-      position: absolute;
-      top: 66px;
-      left: 33px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-      background-position: -27px -54px;
-   }
-   .inner8 {
-      position: absolute;
-      top: 66px;
-      left: 66px;
-      width: 27px;
-      height: 27px;
-      background-image: url("border.png");
-   }
-</style>
-
-<div class="outer">
-   <div class="inner1"></div>
-   <div class="inner2"></div>
-   <div class="inner3"></div>
-   <div class="inner4"></div>
-   <div class="inner5"></div>
-   <div class="inner6"></div>
-   <div class="inner7"></div>
-   <div class="inner8"></div>
-</div>
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-non-multiple-expected.png b/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-non-multiple-expected.png
new file mode 100644
index 0000000..1a59991e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-repeat-space-non-multiple-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-scaled-gradient-expected.png b/third_party/WebKit/LayoutTests/fast/borders/border-image-scaled-gradient-expected.png
index 3e765e93..709f824 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-scaled-gradient-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-scaled-gradient-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/borders/border-image-slice-constrained-expected.png b/third_party/WebKit/LayoutTests/fast/borders/border-image-slice-constrained-expected.png
index 98897c7..eea3a1d4 100644
--- a/third_party/WebKit/LayoutTests/fast/borders/border-image-slice-constrained-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/borders/border-image-slice-constrained-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-svg-expected.txt b/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-svg-expected.txt
deleted file mode 100644
index e171b1b..0000000
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-svg-expected.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-Test createImageBitmap from a SVG image.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS bitmap.width is 200
-PASS bitmap.height is 200
-PASS d[0] is 0
-PASS d[1] is 0
-PASS d[2] is 255
-PASS d[3] is 255
-PASS d[0] is 0
-PASS d[1] is 0
-PASS d[2] is 255
-PASS d[3] is 255
-PASS d[0] is 0
-PASS d[1] is 0
-PASS d[2] is 255
-PASS d[3] is 255
-PASS d[0] is 0
-PASS d[1] is 0
-PASS d[2] is 255
-PASS d[3] is 255
-PASS bitmap.width is 50
-PASS bitmap.height is 50
-PASS d[0] is 0
-PASS d[1] is 0
-PASS d[2] is 255
-PASS d[3] is 255
-PASS d[0] is 0
-PASS d[1] is 0
-PASS d[2] is 255
-PASS d[3] is 255
-PASS d[0] is 0
-PASS d[1] is 0
-PASS d[2] is 255
-PASS d[3] is 255
-PASS d[0] is 0
-PASS d[1] is 0
-PASS d[2] is 255
-PASS d[3] is 255
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-svg.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-svg.html
index bd28ef5..8b37e811 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-svg.html
+++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-createImageBitmap-svg.html
@@ -1,62 +1,90 @@
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test.js"></script>
-</head>
-<body>
+<!DOCTYPE HTML>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
 <script>
-
-description("Test createImageBitmap from a SVG image.");
-window.jsTestIsAsync = true;
-
-function shouldBeBlue(x, y) {
+function shouldBeGreen(x, y) {
     d = ctx.getImageData(x, y, 1, 1).data;
-    shouldBeEqualToNumber("d[0]", 0);
-    shouldBeEqualToNumber("d[1]", 0);
-    shouldBeEqualToNumber("d[2]", 255);
-    shouldBeEqualToNumber("d[3]", 255);
+    assert_array_equals(d, [0, 128, 0, 255]);
+}
+
+function shouldBeTransparent(x, y) {
+    d = ctx.getImageData(x, y, 1, 1).data;
+    assert_array_equals(d, [0, 0, 0, 0]);
 }
 
 function checkBitmap(imageBitmap, width, height)
 {
     bitmap = imageBitmap;
-    if (width == 200) {
-        shouldBe("bitmap.width", "200");
-        shouldBe("bitmap.height", "200");
-    } else {
-        shouldBe("bitmap.width", "50");
-        shouldBe("bitmap.height", "50");
-    }
+    assert_equals(bitmap.width, width);
+    assert_equals(bitmap.height, height);
+    var half_width = width / 2;
+    var half_height = height / 2;
     ctx.clearRect(0, 0, 200, 200);
     ctx.drawImage(bitmap, 0, 0);
-    shouldBeBlue(0, 0);
-    shouldBeBlue(0, width - 1);
-    shouldBeBlue(height - 1, 0);
-    shouldBeBlue(height - 1, width - 1);
+    shouldBeGreen(0, 0);
+    shouldBeGreen(0, half_height - 1);
+    shouldBeGreen(half_width - 1, 0);
+    shouldBeGreen(half_width - 1, half_height - 1);
+    shouldBeTransparent(0, height - 1);
+    shouldBeTransparent(width - 1, 0);
+    shouldBeTransparent(width - 1, height - 1);
 }
 
+function checkFlippedBitmap(imageBitmap, width, height)
+{
+    bitmap = imageBitmap;
+    assert_equals(bitmap.width, width);
+    assert_equals(bitmap.height, height);
+    var half_width = width / 2;
+    var half_height = height / 2;
+    ctx.clearRect(0, 0, 200, 200);
+    ctx.drawImage(bitmap, 0, 0);
+    shouldBeTransparent(0, 0);
+    shouldBeTransparent(0, half_height - 1);
+    shouldBeTransparent(half_width - 1, 0);
+    shouldBeTransparent(half_width - 1, half_height - 1);
+    shouldBeGreen(0, half_height);
+    shouldBeGreen(half_width - 1, half_height);
+    shouldBeGreen(0, height - 1);
+    shouldBeGreen(half_width - 1, height - 1);
+}
+
+function generateTests() {
+    imageBitmaps = {};
+    var p1 = createImageBitmap(image).then(function(image) { imageBitmaps.noResize = image });
+    var p2 = createImageBitmap(image, {resizeWidth: 50, resizeHeight: 50, resizeQuality: "high"}).then(function(image) { imageBitmaps.resizeDown = image });
+    var p3 = createImageBitmap(image, 50, 50, 100, 100).then(function(image) { imageBitmaps.cropCenter = image });
+    var p4 = createImageBitmap(image, 50, 50, 100, 100, {resizeWidth: 200, resizeHeight: 200, resizeQuality: "high"}).then(function(image) { imageBitmaps.cropResizeUp = image });
+    var p5 = createImageBitmap(image, 50, 50, 100, 100, {resizeWidth: 50, resizeHeight: 50, resizeQuality: "high"}).then(function(image) { imageBitmaps.cropResizeDown = image });
+    var p6 = createImageBitmap(image, {imageOrientation: "flipY"}).then(function(image) { imageBitmaps.noResizeFlip = image });
+    var p7 = createImageBitmap(image, 50, 50, 100, 100, {imageOrientation: "flipY"}).then(function(image) { imageBitmaps.cropCenterFlip = image });
+    var p8 = createImageBitmap(image, {resizeWidth: 100, resizeHeight: 100, resizeQuality: "high", imageOrientation: "flipY"}).then(function(image) { imageBitmaps.resizeFlip = image });
+    var p9 = createImageBitmap(image, 50, 50, 100, 100, {resizeWidth: 200, resizeHeight: 200, resizeQuality: "high", imageOrientation: "flipY"}).then(function(image) { imageBitmaps.cropResizeFlip = image });
+    return Promise.all([p1, p2, p3, p4, p5, p6, p7, p8, p9]).then(t.step_func_done(function() {
+        checkBitmap(imageBitmaps.noResize, 200, 200);
+        checkBitmap(imageBitmaps.resizeDown, 50, 50);
+        checkBitmap(imageBitmaps.cropCenter, 100, 100);
+        checkBitmap(imageBitmaps.cropResizeUp, 200, 200);
+        checkBitmap(imageBitmaps.cropResizeDown, 50, 50);
+        checkFlippedBitmap(imageBitmaps.noResizeFlip, 200, 200);
+        checkFlippedBitmap(imageBitmaps.cropCenterFlip, 100, 100);
+        checkFlippedBitmap(imageBitmaps.resizeFlip, 100, 100);
+        checkFlippedBitmap(imageBitmaps.cropResizeFlip, 200, 200);
+    }), t.step_func_done(function() {
+        assert_true(false, 'Promise rejected');
+    }));
+}
+
+var t = async_test('createImageBitmap from svg');
+    
 var canvas = document.createElement("canvas");
 canvas.setAttribute("width", "200");
 canvas.setAttribute("height", "200");
 var ctx = canvas.getContext("2d");
-var bitmap;
 
 var image = new Image();
-image.onload = function() {
-    imageBitmaps = {};
-    var p1 = createImageBitmap(image).then(function(image) { imageBitmaps.noResize = image });
-    var p2 = createImageBitmap(image, {resizeWidth: 50, resizeHeight: 50, resizeQuality: "high"}).then(function(image) { imageBitmaps.resize = image });
-    Promise.all([p1, p2]).then(function() {
-        checkBitmap(imageBitmaps.noResize, 200, 200);
-        checkBitmap(imageBitmaps.resize, 50, 50);
-        finishJSTest();
-    }, function (e) {
-        testFailed("createImageBitmap promise rejected: " + e);
-        finishJSTest();
-    });
-}
-image.src = '../../svg/as-image/resources/200x200-blue-rect.svg';
-
+image.onload = t.step_func(function() {
+    return generateTests();
+});
+image.src = '../../svg/as-image/resources/100px-green-rect.svg';
 </script>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/canvas-fillPath-gradient-shadow.html b/third_party/WebKit/LayoutTests/fast/canvas/canvas-fillPath-gradient-shadow.html
index 2b9c881..db7bec8 100644
--- a/third_party/WebKit/LayoutTests/fast/canvas/canvas-fillPath-gradient-shadow.html
+++ b/third_party/WebKit/LayoutTests/fast/canvas/canvas-fillPath-gradient-shadow.html
@@ -60,10 +60,10 @@
             ['TestAlphaShadow 5', ctx.getImageData(475, 150, 1, 1).data, [ 255, 0, 0, 64], 4, 15],
 
             ['TestBlurryShadow 1', ctx.getImageData(400, 400, 1, 1).data, [ 0, 0, 0, 0, 0], 0, 0],
-            ['TestBlurryShadow 2', ctx.getImageData(400, 300, 1, 1).data, [ 255, 0, 0, 31], 4, 15],
-            ['TestBlurryShadow 3', ctx.getImageData(400, 500, 1, 1).data, [ 255, 0, 0, 31], 4, 15],
-            ['TestBlurryShadow 4', ctx.getImageData(300, 400, 1, 1).data, [ 255, 0, 0, 31], 4, 15],
-            ['TestBlurryShadow 5', ctx.getImageData(500, 400, 1, 1).data, [ 255, 0, 0, 31], 4, 15],
+            ['TestBlurryShadow 2', ctx.getImageData(400, 300, 1, 1).data, [ 255, 0, 0, 31], 9, 15],
+            ['TestBlurryShadow 3', ctx.getImageData(400, 500, 1, 1).data, [ 255, 0, 0, 31], 9, 15],
+            ['TestBlurryShadow 4', ctx.getImageData(300, 400, 1, 1).data, [ 255, 0, 0, 31], 9, 15],
+            ['TestBlurryShadow 5', ctx.getImageData(500, 400, 1, 1).data, [ 255, 0, 0, 31], 9, 15],
 
             ['TestRotatedAlphaShadow 1', ctx.getImageData(400, 650, 1, 1).data, [ 0, 0, 0, 0, 0], 0, 0],
             ['TestRotatedAlphaShadow 2', ctx.getImageData(400, 575, 1, 1).data, [ 255, 0, 0, 64], 4, 15],
@@ -72,10 +72,10 @@
             ['TestRotatedAlphaShadow 5', ctx.getImageData(475, 650, 1, 1).data, [ 255, 0, 0, 64], 4, 15],
 
             ['TestRotatedBlurryShadow 1', ctx.getImageData(400, 900, 1, 1).data, [ 0, 0, 0, 0, 0], 0, 0],
-            ['TestRotatedBlurryShadow 2', ctx.getImageData(400, 800, 1, 1).data, [ 255, 0, 0, 31], 4, 15],
-            ['TestRotatedBlurryShadow 3', ctx.getImageData(400, 1000, 1, 1).data, [ 255, 0, 0, 31], 4, 15],
-            ['TestRotatedBlurryShadow 4', ctx.getImageData(300, 900, 1, 1).data, [ 255, 0, 0, 31], 4, 15],
-            ['TestRotatedBlurryShadow 5', ctx.getImageData(500, 900, 1, 1).data, [ 255, 0, 0, 31], 4, 15],    
+            ['TestRotatedBlurryShadow 2', ctx.getImageData(400, 800, 1, 1).data, [ 255, 0, 0, 31], 9, 15],
+            ['TestRotatedBlurryShadow 3', ctx.getImageData(400, 1000, 1, 1).data, [ 255, 0, 0, 31], 9, 15],
+            ['TestRotatedBlurryShadow 4', ctx.getImageData(300, 900, 1, 1).data, [ 255, 0, 0, 31], 9, 15],
+            ['TestRotatedBlurryShadow 5', ctx.getImageData(500, 900, 1, 1).data, [ 255, 0, 0, 31], 9, 15],    
         ];
 
 generate_tests(testPixelShadow, testScenarios);
diff --git a/third_party/WebKit/LayoutTests/fast/canvas/patternfill-repeat-expected.html b/third_party/WebKit/LayoutTests/fast/canvas/patternfill-repeat-expected.html
deleted file mode 100644
index 4272fc0..0000000
--- a/third_party/WebKit/LayoutTests/fast/canvas/patternfill-repeat-expected.html
+++ /dev/null
@@ -1,73 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
- <head>
-  <title>createPattern repeat test</title>
-  <style> canvas { border:solid #000 } </style>
-  <script>
-   if (window.testRunner) {
-     testRunner.waitUntilDone();
-   }
-   window.onload = function(){
-    var i = new Image();
-    i.src = "resources/apple.gif";
-    i.onload = function() {
-        var ctx = document.getElementsByTagName('canvas')[0].getContext('2d');
-    
-        var w = i.width;
-        var h = i.height;
-    	//ctx.strokeWidth(1.0);
-    	ctx.translate(10, 10);
-	ctx.save();
-        ctx.beginPath();
-        ctx.rect(0, 0, 150, 150);
-        ctx.clip();
-    	ctx.drawImage(i, 0, 0);
-        ctx.drawImage(i, 0, h);
-        ctx.drawImage(i, 0, 2*h);
-        ctx.drawImage(i, w, 0);
-        ctx.drawImage(i, w, h);
-        ctx.drawImage(i, w, 2*h);
-        ctx.drawImage(i, 2*w, 0);
-        ctx.drawImage(i, 2*w, h);
-        ctx.drawImage(i, 2*w, 2*h);
-        ctx.restore();
-
-    	ctx.translate(0, 160);
-        ctx.save();
-        ctx.beginPath();
-        ctx.rect(0, 0, 150, 150);
-        ctx.clip();
-        ctx.drawImage(i, 0, 0);
-        ctx.drawImage(i, w, 0);
-        ctx.drawImage(i, 2*w, 0);
-        ctx.restore();
- 
-    	ctx.translate(160, 0);
-        ctx.save()
-        ctx.beginPath();
-        ctx.rect(0, 0, 150, 150);
-        ctx.clip();
-        ctx.drawImage(i, 0, 0);
-        ctx.restore();
-    
-    	ctx.translate(0, -160);
-        ctx.save();
-        ctx.beginPath();
-        ctx.rect(0, 0, 150, 150);
-        ctx.clip();
-        ctx.drawImage(i, 0, 0);
-        ctx.drawImage(i, 0, h);
-        ctx.drawImage(i, 0, 2*h);
-        ctx.restore();
-    	
-    	if (window.testRunner)
-    	    testRunner.notifyDone();
-    }
-   }
-  </script>
- </head>
- <body>
-  <p>There should be one big square below containing four squares. Top left square should be filled with 3 rows of 2 and bit Apple images. Top right square should be 2 and a bit rows with one Apple image column along the left edge of the square. Bottom left square should be one row with three Apple images along the top of the square. Bottom right square should be one Apple image in top left corner.</p>
-  <p><canvas height="330" width="330"></canvas></p>
- </body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/fast/css/text-overflow-ellipsis-multiple-shadows-expected.html b/third_party/WebKit/LayoutTests/fast/css/text-overflow-ellipsis-multiple-shadows-expected.html
deleted file mode 100644
index 8bd5b0a..0000000
--- a/third_party/WebKit/LayoutTests/fast/css/text-overflow-ellipsis-multiple-shadows-expected.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <style>
-      .testDiv {
-        position: absolute;
-        left: 0;
-        top: 0;
-        overflow: hidden;
-        text-overflow: ellipsis;
-        font-size: 72px;
-        width: 2em;
-      }
-    </style>
-  </head>
-  <body>
-    <div class="testDiv" style="top: 16px; color: blue">Blink</div>
-    <div class="testDiv" style="top: 8px; color: green">Blink</div>
-    <div class="testDiv">Blink</div>
-  </body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/fast/gradients/background-clipped-expected.png b/third_party/WebKit/LayoutTests/fast/gradients/background-clipped-expected.png
index 323a34b..ddf6ca5 100644
--- a/third_party/WebKit/LayoutTests/fast/gradients/background-clipped-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/gradients/background-clipped-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient-expected.png b/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient-expected.png
index 182063c..b601c28 100644
--- a/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient-sides-and-corners-expected.png b/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient-sides-and-corners-expected.png
index 8408d50..2462925 100644
--- a/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient-sides-and-corners-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/gradients/border-image-gradient-sides-and-corners-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/gradients/unprefixed-linear-gradients-color-hints-expected.png b/third_party/WebKit/LayoutTests/fast/gradients/unprefixed-linear-gradients-color-hints-expected.png
deleted file mode 100644
index 37f6dc1..0000000
--- a/third_party/WebKit/LayoutTests/fast/gradients/unprefixed-linear-gradients-color-hints-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/hidpi/gradient-with-scaled-ancestor-expected.png b/third_party/WebKit/LayoutTests/fast/hidpi/gradient-with-scaled-ancestor-expected.png
index 86d11241..598ee8a 100644
--- a/third_party/WebKit/LayoutTests/fast/hidpi/gradient-with-scaled-ancestor-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/hidpi/gradient-with-scaled-ancestor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/border-radius-with-image-expected.png b/third_party/WebKit/LayoutTests/fast/table/border-radius-with-image-expected.png
index b8b2d62..ba18451 100644
--- a/third_party/WebKit/LayoutTests/fast/table/border-radius-with-image-expected.png
+++ b/third_party/WebKit/LayoutTests/fast/table/border-radius-with-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/fast/table/tbody-background-image-repeat-x-expected.html b/third_party/WebKit/LayoutTests/fast/table/tbody-background-image-repeat-x-expected.html
deleted file mode 100644
index 05da688..0000000
--- a/third_party/WebKit/LayoutTests/fast/table/tbody-background-image-repeat-x-expected.html
+++ /dev/null
@@ -1,6 +0,0 @@
-<!DOCTYPE html>
-<style>
-</style>
-<p>crbug.com/35697: The image should be tiled across the first row of the table.</p>
-<div style="width: 100%; height: 76px; background:url(../../images/resources/border-image-srgb-color-profile.png);">
-</div>
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/application-panel/resources-panel-websql-expected.txt b/third_party/WebKit/LayoutTests/http/tests/inspector/application-panel/resources-panel-websql-expected.txt
new file mode 100644
index 0000000..e61f15b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/application-panel/resources-panel-websql-expected.txt
@@ -0,0 +1,85 @@
+Tests Application Panel WebSQL support.
+
+Initial state:
+Application
+  Manifest (selected)
+  Service Workers
+  Clear storage
+Storage
+  Local Storage
+    http://127.0.0.1:8000
+  Session Storage
+    http://127.0.0.1:8000
+  IndexedDB
+  Web SQL
+  Cookies
+    http://127.0.0.1:8000
+Cache
+  Cache Storage
+  Application Cache
+Frames
+  top
+    Scripts
+      console-test.js
+      indexeddb-test.js
+      inspector-test.js
+      json-value.js
+      resources-test.js
+    resources-panel-websql.html
+Found: true
+Database created state:
+Application
+  Manifest
+  Service Workers
+  Clear storage
+Storage
+  Local Storage
+    http://127.0.0.1:8000
+  Session Storage
+    http://127.0.0.1:8000
+  IndexedDB
+  Web SQL
+    inspector-test-db (selected)
+  Cookies
+    http://127.0.0.1:8000
+Cache
+  Cache Storage
+  Application Cache
+Frames
+  top
+    Scripts
+      console-test.js
+      indexeddb-test.js
+      inspector-test.js
+      json-value.js
+      resources-test.js
+    resources-panel-websql.html
+Table added:
+Application
+  Manifest
+  Service Workers
+  Clear storage
+Storage
+  Local Storage
+    http://127.0.0.1:8000
+  Session Storage
+    http://127.0.0.1:8000
+  IndexedDB
+  Web SQL
+    inspector-test-db (selected)
+      table1
+  Cookies
+    http://127.0.0.1:8000
+Cache
+  Cache Storage
+  Application Cache
+Frames
+  top
+    Scripts
+      console-test.js
+      indexeddb-test.js
+      inspector-test.js
+      json-value.js
+      resources-test.js
+    resources-panel-websql.html
+
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/application-panel/resources-panel-websql.html b/third_party/WebKit/LayoutTests/http/tests/inspector/application-panel/resources-panel-websql.html
new file mode 100644
index 0000000..4c2b5040
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/application-panel/resources-panel-websql.html
@@ -0,0 +1,83 @@
+<html>
+<head>
+<script>
+function parse(val) {
+    // This is here for the JSON file imported via the script tag below
+}
+</script>
+<script src="../inspector-test.js"></script>
+<script src="../resources-test.js"></script>
+<script src="../console-test.js"></script>
+<script src="../resources/json-value.js"></script>
+<script src="../indexeddb/indexeddb-test.js"></script>
+<script>
+
+async function test()
+{
+
+    function dump(node, prefix)
+    {
+        for (var child of node.children()) {
+            InspectorTest.addResult(prefix + child.listItemElement.textContent + (child.selected ? " (selected)" : ""));
+            dump(child, prefix + "  ");
+        }
+    }
+
+    function dumpCurrentState(label) {
+        InspectorTest.addResult(label);
+        dump(UI.panels.resources._sidebar._sidebarTree.rootElement(), "");
+    }
+
+    function findTreeElement(parent, path) {
+        if (path.length === 0)
+            return parent;
+        var child = parent.children().find(child => child.title === path[0]);
+        if (!child)
+            return null;
+        child.expand();
+        return findTreeElement(child, path.slice(1));
+    }
+
+    async function createTable(queryView) {
+        queryView._prompt.setText('CREATE TABLE table1 (id INTEGER PRIMARY KEY ASC, text_field TEXT)');
+        queryView._enterKeyPressed(new KeyboardEvent('keydown'));
+        await queryView.once(Resources.DatabaseQueryView.Events.SchemaUpdated);
+        return new Promise(resolve => setTimeout(resolve));
+    }
+    UI.viewManager.showView('resources');
+    dumpCurrentState('Initial state:');
+
+    await InspectorTest.evaluateInPagePromise('openDatabase("inspector-test-db", "1.0", "Database for inspector test", 1024*1024)');
+
+    var parent = UI.panels.resources._sidebar._sidebarTree.rootElement();
+    var databaseElement = findTreeElement(parent, ['Storage', 'Web SQL', 'inspector-test-db']);
+
+    InspectorTest.addResult("Found: " + !!databaseElement);
+
+    if (!databaseElement)
+        return;
+
+    databaseElement.select();
+    dumpCurrentState("Database created state:");
+
+    var queryView = UI.panels.resources.visibleView;
+    if (!queryView instanceof Resources.DatabaseQueryView) {
+        InspectorTest.addResult("Not a Resources.DatabaseQueryView");
+        return;
+    }
+
+    await createTable(queryView);
+    while (!findTreeElement(databaseElement, ["table1"])) {
+        databaseElement.expand();
+        await new Promise(resolve => setTimeout(resolve));
+    }
+
+    dumpCurrentState("Table added:");
+    InspectorTest.completeTest();
+}
+</script>
+</head>
+<body onload="runTest()">
+<p>Tests Application Panel WebSQL support.</p>
+</body>
+</html>
diff --git a/third_party/WebKit/LayoutTests/http/tests/previews/client-lofi-sprite-expected.png b/third_party/WebKit/LayoutTests/http/tests/previews/client-lofi-sprite-expected.png
index 4554713c..d83c488 100644
--- a/third_party/WebKit/LayoutTests/http/tests/previews/client-lofi-sprite-expected.png
+++ b/third_party/WebKit/LayoutTests/http/tests/previews/client-lofi-sprite-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/cross-fade-overflow-position-expected.png b/third_party/WebKit/LayoutTests/images/cross-fade-overflow-position-expected.png
index 1ba6f8c..e1ec9b50 100644
--- a/third_party/WebKit/LayoutTests/images/cross-fade-overflow-position-expected.png
+++ b/third_party/WebKit/LayoutTests/images/cross-fade-overflow-position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/images/cross-fade-tiled-expected.png b/third_party/WebKit/LayoutTests/images/cross-fade-tiled-expected.png
index 46b7397..8e2d2d38 100644
--- a/third_party/WebKit/LayoutTests/images/cross-fade-tiled-expected.png
+++ b/third_party/WebKit/LayoutTests/images/cross-fade-tiled-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-format-array-prototype-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-format-array-prototype-expected.txt
index 1374172..ba59c88 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-format-array-prototype-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-format-array-prototype-expected.txt
@@ -15,23 +15,23 @@
 []
 console-format-array-prototype.html:4 []
 a1
-[undefined × 1]
-console-format-array-prototype.html:4 [undefined × 1]
+[empty × 1]
+console-format-array-prototype.html:4 [empty × 1]
 a2
-(5) [undefined × 5]
-console-format-array-prototype.html:4 (5) [undefined × 5]
+(5) [empty × 5]
+console-format-array-prototype.html:4 (5) [empty × 5]
 a3
-(3) [undefined × 1, 2, 3]
-console-format-array-prototype.html:4 (3) [undefined × 1, 2, 3]
+(3) [empty × 1, 2, 3]
+console-format-array-prototype.html:4 (3) [empty × 1, 2, 3]
 a4
-(15) [undefined × 15]
-console-format-array-prototype.html:4 (15) [undefined × 15]
+(15) [empty × 15]
+console-format-array-prototype.html:4 (15) [empty × 15]
 a5
-(15) [undefined × 8, 8, undefined × 6]
-console-format-array-prototype.html:4 (15) [undefined × 8, 8, undefined × 6]
+(15) [empty × 8, 8, empty × 6]
+console-format-array-prototype.html:4 (15) [empty × 8, 8, empty × 6]
 a6
-(15) [0, undefined × 9, 10, undefined × 4]
-console-format-array-prototype.html:4 (15) [0, undefined × 9, 10, undefined × 4]
+(15) [0, empty × 9, 10, empty × 4]
+console-format-array-prototype.html:4 (15) [0, empty × 9, 10, empty × 4]
 a7
 (15) [3: 4, index0: 0, index1: 1, index2: 2, index3: 3, index4: 4, …]
 console-format-array-prototype.html:4 (15) [3: 4, index0: 0, index1: 1, index2: 2, index3: 3, index4: 4, …]
@@ -39,8 +39,8 @@
 (10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 console-format-array-prototype.html:4 (10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
 a9
-(11) [undefined × 1, 1, 2, 3, 4, undefined × 1, 6, 7, 8, 9, undefined × 1, foo: "bar"]
-console-format-array-prototype.html:4 (11) [undefined × 1, 1, 2, 3, 4, undefined × 1, 6, 7, 8, 9, undefined × 1, foo: "bar"]
+(11) [empty × 1, 1, 2, 3, 4, empty × 1, 6, 7, 8, 9, empty × 1, foo: "bar"]
+console-format-array-prototype.html:4 (11) [empty × 1, 1, 2, 3, 4, empty × 1, 6, 7, 8, 9, empty × 1, foo: "bar"]
 a10
 Array {}
 console-format-array-prototype.html:4 Array {}
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-format-collections-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-format-collections-expected.txt
index c206d0c6..f8413095 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-format-collections-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-format-collections-expected.txt
@@ -64,8 +64,8 @@
 console-format-collections.html:44 NonArrayWithLength {keys: Array(0)}
 console-format-collections.html:51 (2) [1, "2", callee: ƒ, Symbol(Symbol.iterator): ƒ]
 console-format-collections.html:55 (3) ["c1", "c2", "c3", value: "c1 c2 c3"]
-console-format-collections.html:58 (5) [undefined × 5]
-console-format-collections.html:59 (4294967295) [undefined × 4294967295]
+console-format-collections.html:58 (5) [empty × 5]
+console-format-collections.html:59 (4294967295) [empty × 4294967295]
 console-format-collections.html:61 ArrayLike {length: -5}
 console-format-collections.html:62 ArrayLike {length: 5.6}
 console-format-collections.html:63 ArrayLike {length: NaN}
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-log-object-with-getter-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-log-object-with-getter-expected.txt
index f9ff72b..f4909dc 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-log-object-with-getter-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-log-object-with-getter-expected.txt
@@ -4,9 +4,9 @@
 Tests that console logging dumps object values defined by getters and allows to expand it.
 
 console-log-object-with-getter.html:25 {}
-console-log-object-with-getter.html:26 (2) [(...), undefined × 1]
+console-log-object-with-getter.html:26 (2) [(...), empty × 1]
 console-log-object-with-getter.html:27 {}
 console-log-object-with-getter.html:25 {}foo: Objecta: 1b: 2__proto__: Objectget foo: ƒ ()set bar: ƒ (x)__proto__: Object console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-object source-code expanded > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element expanded > selection fill > console-object-preview > object-properties-preview source-code > object-state-note info-note > children expanded > parent expanded > name > object-properties-section-separator > object-value-object value > children expanded > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-function value > object-value-function-prefix > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-function value > object-value-function-prefix > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
-console-log-object-with-getter.html:26 (2) [(...), undefined × 1]0: 1length: 2get 0: ƒ ()set 1: ƒ (x)__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-array source-code expanded > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element expanded > selection fill > console-object-preview > object-description > object-properties-preview source-code > object-value-accessor > object-value-undefined > object-state-note info-note > children expanded > name > object-properties-section-separator > object-value-number value > children > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-number value > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-function value > object-value-function-prefix > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-function value > object-value-function-prefix > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-array value > children
+console-log-object-with-getter.html:26 (2) [(...), empty × 1]0: 1length: 2get 0: ƒ ()set 1: ƒ (x)__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-array source-code expanded > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element expanded > selection fill > console-object-preview > object-description > object-properties-preview source-code > object-value-accessor > object-value-undefined > object-state-note info-note > children expanded > name > object-properties-section-separator > object-value-number value > children > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-number value > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-function value > object-value-function-prefix > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-function value > object-value-function-prefix > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-array value > children
 console-log-object-with-getter.html:27 {}error: [Exception: Error: myError]function: [Exception: ƒ ()]number: [Exception: 123]string: [Exception: "myString"]get error: ƒ error()get function: ƒ function()get number: ƒ number()get string: ƒ string()__proto__: Object console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-object source-code expanded > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element expanded > selection fill > console-object-preview > object-properties-preview source-code > object-state-note info-note > children expanded > name > object-properties-section-separator > error value > object-value-error > children > name > object-properties-section-separator > error value > object-value-function > object-value-function-prefix > children > name > object-properties-section-separator > error value > object-value-number > children > name > object-properties-section-separator > error value > object-value-string > object-value-string-quote > object-value-string-quote > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-function value > object-value-function-prefix > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-function value > object-value-function-prefix > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-function value > object-value-function-prefix > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-function value > object-value-function-prefix > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
 
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-object-preview-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-object-preview-expected.txt
index b161327c..e17f581 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-object-preview-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-object-preview-expected.txt
@@ -46,11 +46,11 @@
 console-object-preview.html:37 Array with gaps and overflow console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text
 console-object-preview.html:42 (5733) [32: 0, 89: 1, 146: 2, 203: 3, 260: 4, 317: 5, 374: 6, 431: 7, 488: 8, 545: 9, 602: 10, 659: 11, 716: 12, 773: 13, 830: 14, 887: 15, 944: 16, 1001: 17, 1058: 18, 1115: 19, 1172: 20, 1229: 21, 1286: 22, 1343: 23, 1400: 24, 1457: 25, 1514: 26, 1571: 27, 1628: 28, 1685: 29, 1742: 30, 1799: 31, 1856: 32, 1913: 33, 1970: 34, 2027: 35, 2084: 36, 2141: 37, 2198: 38, 2255: 39, 2312: 40, 2369: 41, 2426: 42, 2483: 43, 2540: 44, 2597: 45, 2654: 46, 2711: 47, 2768: 48, 2825: 49, 2882: 50, 2939: 51, 2996: 52, 3053: 53, 3110: 54, 3167: 55, 3224: 56, 3281: 57, 3338: 58, 3395: 59, 3452: 60, 3509: 61, 3566: 62, 3623: 63, 3680: 64, 3737: 65, 3794: 66, 3851: 67, 3908: 68, 3965: 69, 4022: 70, 4079: 71, 4136: 72, 4193: 73, 4250: 74, 4307: 75, 4364: 76, 4421: 77, 4478: 78, 4535: 79, 4592: 80, 4649: 81, 4706: 82, 4763: 83, 4820: 84, 4877: 85, 4934: 86, 4991: 87, 5048: 88, 5105: 89, 5162: 90, 5219: 91, 5276: 92, 5333: 93, 5390: 94, 5447: 95, 5504: 96, 5561: 97, 5618: 98, 5675: 99, …] console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-array source-code > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element > selection fill > console-object-preview > object-description > object-properties-preview source-code > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > object-state-note info-note > children
 console-object-preview.html:44 Array with gaps without overflow console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text
-console-object-preview.html:49 (5619) [undefined × 32, 0, undefined × 56, 1, undefined × 56, 2, undefined × 56, 3, undefined × 56, 4, undefined × 56, 5, undefined × 56, 6, undefined × 56, 7, undefined × 56, 8, undefined × 56, 9, undefined × 56, 10, undefined × 56, 11, undefined × 56, 12, undefined × 56, 13, undefined × 56, 14, undefined × 56, 15, undefined × 56, 16, undefined × 56, 17, undefined × 56, 18, undefined × 56, 19, undefined × 56, 20, undefined × 56, 21, undefined × 56, 22, undefined × 56, 23, undefined × 56, 24, undefined × 56, 25, undefined × 56, 26, undefined × 56, 27, undefined × 56, 28, undefined × 56, 29, undefined × 56, 30, undefined × 56, 31, undefined × 56, 32, undefined × 56, 33, undefined × 56, 34, undefined × 56, 35, undefined × 56, 36, undefined × 56, 37, undefined × 56, 38, undefined × 56, 39, undefined × 56, 40, undefined × 56, 41, undefined × 56, 42, undefined × 56, 43, undefined × 56, 44, undefined × 56, 45, undefined × 56, 46, undefined × 56, 47, undefined × 56, 48, undefined × 56, console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-array source-code > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element > selection fill > console-object-preview > object-description > object-properties-preview source-code > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-state-note info-note > children
+console-object-preview.html:49 (5619) [empty × 32, 0, empty × 56, 1, empty × 56, 2, empty × 56, 3, empty × 56, 4, empty × 56, 5, empty × 56, 6, empty × 56, 7, empty × 56, 8, empty × 56, 9, empty × 56, 10, empty × 56, 11, empty × 56, 12, empty × 56, 13, empty × 56, 14, empty × 56, 15, empty × 56, 16, empty × 56, 17, empty × 56, 18, empty × 56, 19, empty × 56, 20, empty × 56, 21, empty × 56, 22, empty × 56, 23, empty × 56, 24, empty × 56, 25, empty × 56, 26, empty × 56, 27, empty × 56, 28, empty × 56, 29, empty × 56, 30, empty × 56, 31, empty × 56, 32, empty × 56, 33, empty × 56, 34, empty × 56, 35, empty × 56, 36, empty × 56, 37, empty × 56, 38, empty × 56, 39, empty × 56, 40, empty × 56, 41, empty × 56, 42, empty × 56, 43, empty × 56, 44, empty × 56, 45, empty × 56, 46, empty × 56, 47, empty × 56, 48, empty × 56, 49, empty × 56, 50, empty × 56, 51, empty × 56, 52, empty × 56, 53, empty × 56, 54, empty × 56, 55, empty × 56, 56, empty × 56, 57, empty × 56, 58, empty × 56, 59, empty × 56, 60, empty × 56, 61, emp console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-array source-code > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element > selection fill > console-object-preview > object-description > object-properties-preview source-code > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-state-note info-note > children
 console-object-preview.html:51 Object with proto console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text
 console-object-preview.html:54 {d: 1} console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-object source-code > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element > selection fill > console-object-preview > object-properties-preview source-code > name > object-value-number > object-state-note info-note > children
 console-object-preview.html:56 Sparse array console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text
-console-object-preview.html:59 (150) [undefined × 50, 50, undefined × 99] console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-array source-code > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element > selection fill > console-object-preview > object-description > object-properties-preview source-code > object-value-undefined > object-value-number > object-value-undefined > object-state-note info-note > children
+console-object-preview.html:59 (150) [empty × 50, 50, empty × 99] console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-array source-code > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element > selection fill > console-object-preview > object-description > object-properties-preview source-code > object-value-undefined > object-value-number > object-value-undefined > object-state-note info-note > children
 console-object-preview.html:61 Dense array with indexes and propeties console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text
 console-object-preview.html:67 (150) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, …] console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-array source-code > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element > selection fill > console-object-preview > object-description > object-properties-preview source-code > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-state-note info-note > children
 console-object-preview.html:69 Object with properties containing whitespaces console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text
@@ -78,11 +78,11 @@
 console-object-preview.html:37 Array with gaps and overflow console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text
 console-object-preview.html:42 (5733) [32: 0, 89: 1, 146: 2, 203: 3, 260: 4, 317: 5, 374: 6, 431: 7, 488: 8, 545: 9, 602: 10, 659: 11, 716: 12, 773: 13, 830: 14, 887: 15, 944: 16, 1001: 17, 1058: 18, 1115: 19, 1172: 20, 1229: 21, 1286: 22, 1343: 23, 1400: 24, 1457: 25, 1514: 26, 1571: 27, 1628: 28, 1685: 29, 1742: 30, 1799: 31, 1856: 32, 1913: 33, 1970: 34, 2027: 35, 2084: 36, 2141: 37, 2198: 38, 2255: 39, 2312: 40, 2369: 41, 2426: 42, 2483: 43, 2540: 44, 2597: 45, 2654: 46, 2711: 47, 2768: 48, 2825: 49, 2882: 50, 2939: 51, 2996: 52, 3053: 53, 3110: 54, 3167: 55, 3224: 56, 3281: 57, 3338: 58, 3395: 59, 3452: 60, 3509: 61, 3566: 62, 3623: 63, 3680: 64, 3737: 65, 3794: 66, 3851: 67, 3908: 68, 3965: 69, 4022: 70, 4079: 71, 4136: 72, 4193: 73, 4250: 74, 4307: 75, 4364: 76, 4421: 77, 4478: 78, 4535: 79, 4592: 80, 4649: 81, 4706: 82, 4763: 83, 4820: 84, 4877: 85, 4934: 86, 4991: 87, 5048: 88, 5105: 89, 5162: 90, 5219: 91, 5276: 92, 5333: 93, 5390: 94, 5447: 95, 5504: 96, 5561: 97, 5618: 98, 5675: 99, …][32 … 5675]5 console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-array source-code expanded > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element expanded > selection fill > console-object-preview > object-description > object-properties-preview source-code > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > name > object-value-number > object-state-note info-note > children expanded > parent object-properties-section-name > selection fill > tree-element-title > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-number value > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-array value > children
 console-object-preview.html:44 Array with gaps without overflow console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text
-console-object-preview.html:49 (5619) [undefined × 32, 0, undefined × 56, 1, undefined × 56, 2, undefined × 56, 3, undefined × 56, 4, undefined × 56, 5, undefined × 56, 6, undefined × 56, 7, undefined × 56, 8, undefined × 56, 9, undefined × 56, 10, undefined × 56, 11, undefined × 56, 12, undefined × 56, 13, undefined × 56, 14, undefined × 56, 15, undefined × 56, 16, undefined × 56, 17, undefined × 56, 18, undefined × 56, 19, undefined × 56, 20, undefined × 56, 21, undefined × 56, 22, undefined × 56, 23, undefined × 56, 24, undefined × 56, 25, undefined × 56, 26, undefined × 56, 27, undefined × 56, 28, undefined × 56, 29, undefined × 56, 30, undefined × 56, 31, undefined × 56, 32, undefined × 56, 33, undefined × 56, 34, undefined × 56, 35, undefined × 56, 36, undefined × 56, 37, undefined × 56, 38, undefined × 56, 39, undefined × 56, 40, undefined × 56, 41, undefined × 56, 42, undefined × 56, 43, undefined × 56, 44, undefined × 56, 45, undefined × 56, 46, undefined × 56, 47, undefined × 56, 48, undefined × 56, console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-array source-code expanded > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element expanded > selection fill > console-object-preview > object-description > object-properties-preview source-code > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-state-note info-note > children expanded > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-number value > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-array value > children
+console-object-preview.html:49 (5619) [empty × 32, 0, empty × 56, 1, empty × 56, 2, empty × 56, 3, empty × 56, 4, empty × 56, 5, empty × 56, 6, empty × 56, 7, empty × 56, 8, empty × 56, 9, empty × 56, 10, empty × 56, 11, empty × 56, 12, empty × 56, 13, empty × 56, 14, empty × 56, 15, empty × 56, 16, empty × 56, 17, empty × 56, 18, empty × 56, 19, empty × 56, 20, empty × 56, 21, empty × 56, 22, empty × 56, 23, empty × 56, 24, empty × 56, 25, empty × 56, 26, empty × 56, 27, empty × 56, 28, empty × 56, 29, empty × 56, 30, empty × 56, 31, empty × 56, 32, empty × 56, 33, empty × 56, 34, empty × 56, 35, empty × 56, 36, empty × 56, 37, empty × 56, 38, empty × 56, 39, empty × 56, 40, empty × 56, 41, empty × 56, 42, empty × 56, 43, empty × 56, 44, empty × 56, 45, empty × 56, 46, empty × 56, 47, empty × 56, 48, empty × 56, 49, empty × 56, 50, empty × 56, 51, empty × 56, 52, empty × 56, 53, empty × 56, 54, empty × 56, 55, empty × 56, 56, empty × 56, 57, empty × 56, 58, empty × 56, 59, empty × 56, 60, empty × 56, 61, emp console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-array source-code expanded > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element expanded > selection fill > console-object-preview > object-description > object-properties-preview source-code > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-state-note info-note > children expanded > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-number value > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-array value > children
 console-object-preview.html:51 Object with proto console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text
 console-object-preview.html:54 {d: 1}d: 1__proto__: Object console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-object source-code expanded > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element expanded > selection fill > console-object-preview > object-properties-preview source-code > name > object-value-number > object-state-note info-note > children expanded > selection fill > name > object-properties-section-separator > object-value-number value > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
 console-object-preview.html:56 Sparse array console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text
-console-object-preview.html:59 (150) [undefined × 50, 50, undefined × 99]50: 50length: 150__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-array source-code expanded > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element expanded > selection fill > console-object-preview > object-description > object-properties-preview source-code > object-value-undefined > object-value-number > object-value-undefined > object-state-note info-note > children expanded > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-number value > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-array value > children
+console-object-preview.html:59 (150) [empty × 50, 50, empty × 99]50: 50length: 150__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-array source-code expanded > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element expanded > selection fill > console-object-preview > object-description > object-properties-preview source-code > object-value-undefined > object-value-number > object-value-undefined > object-state-note info-note > children expanded > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-number value > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-array value > children
 console-object-preview.html:61 Dense array with indexes and propeties console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text
 console-object-preview.html:67 (150) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, …][0 … 99][100 … 149]property_0: 0property_1: 1property_2: 2property_3: 3property_4: 4property_5: 5property_6: 6property_7: 7property_8: 8property_9: 9property_10: 10property_11: 11property_12: 12property_13: 13property_14: 14property_15: 15property_16: 16property_17: 17property_18: 18property_19: 19property_20: 20property_21: 21property_22: 22property_23: 23property_24: 24property_25: 25property_26: 26property_27: 27property_28: 28property_29: 29property_30: 30property_31: 31property_32: 32property_33: 33property_34: 34property_35: 35property_36: 36property_37: 37property_38: 38property_3 console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text > console-view-object-properties-section object-value-array source-code expanded > tree-outline-disclosure tree-outline-disclosure-hide-overflow > tree-outline source-code object-properties-section > parent object-properties-section-root-element expanded > selection fill > console-object-preview > object-description > object-properties-preview source-code > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-value-number > object-state-note info-note > children expanded > parent object-properties-section-name > selection fill > tree-element-title > children > parent object-properties-section-name > selection fill > tree-element-title > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-number value > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-array value > children
 console-object-preview.html:69 Object with properties containing whitespaces console-message > source-code > console-message-anchor > devtools-link > hidden console-message-badge > hide-badge-title > console-message-text
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/debugger-inline-values-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/debugger-inline-values-expected.txt
index 55cde59..929df03 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/debugger-inline-values-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/debugger-inline-values-expected.txt
@@ -59,7 +59,7 @@
 [ 8]       debugger; 	
 [ 9]       var a = { k: 1 }; 	 a = {k: 1}
 [10]       var b = [1, 2, 3, 4, 5]; 	 b = (5) [1, 2, 3, 4, 5]
-[11]       var c = new Array(100); c[10] = 1; 	 c = (100) [undefined × 10, 1, undefined × 89]
+[11]       var c = new Array(100); c[10] = 1; 	 c = (100) [empty × 10, 1, empty × 89]
 [12] >     a.k = 2; 	
 [13]       a.l = window; 	
 [14]       b[1]++; 	
@@ -70,7 +70,7 @@
 [ 8]       debugger; 	
 [ 9]       var a = { k: 1 }; 	 a = {k: 2}
 [10]       var b = [1, 2, 3, 4, 5]; 	 b = (5) [1, 2, 3, 4, 5]
-[11]       var c = new Array(100); c[10] = 1; 	 c = (100) [undefined × 10, 1, undefined × 89]
+[11]       var c = new Array(100); c[10] = 1; 	 c = (100) [empty × 10, 1, empty × 89]
 [12]       a.k = 2; 	 a = {k: 2}
 [13] >     a.l = window; 	
 [14]       b[1]++; 	
@@ -81,7 +81,7 @@
 [ 8]       debugger; 	
 [ 9]       var a = { k: 1 }; 	 a = {k: 2, l: Window}
 [10]       var b = [1, 2, 3, 4, 5]; 	 b = (5) [1, 2, 3, 4, 5]
-[11]       var c = new Array(100); c[10] = 1; 	 c = (100) [undefined × 10, 1, undefined × 89]
+[11]       var c = new Array(100); c[10] = 1; 	 c = (100) [empty × 10, 1, empty × 89]
 [12]       a.k = 2; 	 a = {k: 2, l: Window}
 [13]       a.l = window; 	 
 [14] >     b[1]++; 	
@@ -92,7 +92,7 @@
 [ 8]       debugger; 	
 [ 9]       var a = { k: 1 }; 	 a = {k: 2, l: Window}
 [10]       var b = [1, 2, 3, 4, 5]; 	 b = (5) [1, 3, 3, 4, 5]
-[11]       var c = new Array(100); c[10] = 1; 	 c = (100) [undefined × 10, 1, undefined × 89]
+[11]       var c = new Array(100); c[10] = 1; 	 c = (100) [empty × 10, 1, empty × 89]
 [12]       a.k = 2; 	 a = {k: 2, l: Window}
 [13]       a.l = window; 	 
 [14]       b[1]++; 	 b = (5) [1, 3, 3, 4, 5]
@@ -103,7 +103,7 @@
 [ 8]       debugger; 	
 [ 9]       var a = { k: 1 }; 	 a = {k: 2, l: Window}
 [10]       var b = [1, 2, 3, 4, 5]; 	 b = (5) [1, 3, body, 4, 5]
-[11]       var c = new Array(100); c[10] = 1; 	 c = (100) [undefined × 10, 1, undefined × 89]
+[11]       var c = new Array(100); c[10] = 1; 	 c = (100) [empty × 10, 1, empty × 89]
 [12]       a.k = 2; 	 a = {k: 2, l: Window}
 [13]       a.l = window; 	 
 [14]       b[1]++; 	 b = (5) [1, 3, body, 4, 5]
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/background-image-paint-invalidation-small-document-expected.png b/third_party/WebKit/LayoutTests/paint/invalidation/background-image-paint-invalidation-small-document-expected.png
index 608f01c4..cc4227b 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/background-image-paint-invalidation-small-document-expected.png
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/background-image-paint-invalidation-small-document-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/page-scale-repaint-expected.png b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/page-scale-repaint-expected.png
index 5b9106a8c..add8c44 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/compositing/page-scale-repaint-expected.png
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/compositing/page-scale-repaint-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/svg/deep-dynamic-updates-expected.png b/third_party/WebKit/LayoutTests/paint/invalidation/svg/deep-dynamic-updates-expected.png
index e7ee6100..7567b36 100644
--- a/third_party/WebKit/LayoutTests/paint/invalidation/svg/deep-dynamic-updates-expected.png
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/svg/deep-dynamic-updates-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/viewport-gradient-background-html-resize-expected.html b/third_party/WebKit/LayoutTests/paint/invalidation/viewport-gradient-background-html-resize-expected.html
deleted file mode 100644
index 0fdc35d..0000000
--- a/third_party/WebKit/LayoutTests/paint/invalidation/viewport-gradient-background-html-resize-expected.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<style>
-body {
-  margin: 0;
-  overflow: hidden;
-}
-div {
-  background: linear-gradient(to bottom, blue, cyan);
-  height: 200px;
-}
-</style>
-<div></div>
-<div></div>
-<div></div>
-<div></div>
diff --git a/third_party/WebKit/LayoutTests/paint/invalidation/viewport-gradient-background-html-resize-expected.png b/third_party/WebKit/LayoutTests/paint/invalidation/viewport-gradient-background-html-resize-expected.png
new file mode 100644
index 0000000..d3afb71
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/paint/invalidation/viewport-gradient-background-html-resize-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/paint/masks/fieldset-mask-expected.png b/third_party/WebKit/LayoutTests/paint/masks/fieldset-mask-expected.png
index 6c74deb..e79038a 100644
--- a/third_party/WebKit/LayoutTests/paint/masks/fieldset-mask-expected.png
+++ b/third_party/WebKit/LayoutTests/paint/masks/fieldset-mask-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/paint/overflow/fixed-background-scroll-window-expected.html b/third_party/WebKit/LayoutTests/paint/overflow/fixed-background-scroll-window-expected.html
deleted file mode 100644
index b8a482d..0000000
--- a/third_party/WebKit/LayoutTests/paint/overflow/fixed-background-scroll-window-expected.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<style>
-::-webkit-scrollbar {
-  display: none;
-}
-</style>
-<body style="height: 600px; background: linear-gradient(red, blue); background-size: 800px 600px;">
-<p style="position: absolute; top: 100px">
-Tests painting of fixed background content in scrolled container.
-Passes if the background doesn't scroll.
-</p>
-</body>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/direct-image-compositing-expected.png b/third_party/WebKit/LayoutTests/platform/linux/compositing/direct-image-compositing-expected.png
index 0c46d4069a..5dcac252 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/compositing/direct-image-compositing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/direct-image-compositing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/compositing/geometry/vertical-scroll-composited-expected.png b/third_party/WebKit/LayoutTests/platform/linux/compositing/geometry/vertical-scroll-composited-expected.png
index 2f459985..82dd348 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/compositing/geometry/vertical-scroll-composited-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/compositing/geometry/vertical-scroll-composited-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/basic/comments-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/basic/comments-expected.png
index 23e7fa2..875a1dbc 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/basic/comments-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/basic/comments-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/basic/containment-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/basic/containment-expected.png
index 94d55899..5e0a8d1d0 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/basic/containment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/basic/containment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/basic/contextual_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/basic/contextual_selectors-expected.png
index 6112d6d..6403012 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/basic/contextual_selectors-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/basic/contextual_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/basic/grouping-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/basic/grouping-expected.png
index 6fa52bc5..3025527f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/basic/grouping-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/basic/grouping-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/basic/id_as_selector-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/basic/id_as_selector-expected.png
index 9a547898..3676b02 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/basic/id_as_selector-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/basic/id_as_selector-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/basic/inheritance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/basic/inheritance-expected.png
index 8afc076b..d75ae9f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/basic/inheritance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/basic/inheritance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border-expected.png
index 662f8b08..39b3e89 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom-expected.png
index fd606fa..b2b486e4 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom_inline-expected.png
index 135de6e..56bc31b 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom_width-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom_width-expected.png
index 3682aeb6..8f463b2 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom_width_inline-expected.png
index 3ad65031..f084174 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_bottom_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_color-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_color-expected.png
index 34585c46..9bda7de 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_color-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_color_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_color_inline-expected.png
index 939bdfc7..d5d5734 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_color_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_color_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_inline-expected.png
index cd8a856..fd2fa92 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left-expected.png
index 801d4af..d1b0593 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left_inline-expected.png
index be4f28885..d2e2a18 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left_width-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left_width-expected.png
index e891fbb..0f87bc8 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left_width_inline-expected.png
index 5b355e1..3880f49 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_left_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right-expected.png
index 411890a..a6a8b0b 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right_inline-expected.png
index 0adb5f86..aa7a52f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right_width-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right_width-expected.png
index 556a3db..25ee29b 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right_width_inline-expected.png
index 3b983872..3978696 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_right_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_style-expected.png
index 5af001f..1da1b49 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_style_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_style_inline-expected.png
index a6816bd0..0230695 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_style_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_style_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top-expected.png
index 6f92c67..86ea8a8 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top_inline-expected.png
index 49cfc71..8a0935ec 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top_width-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top_width-expected.png
index 8a3c921..7e8a215 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top_width_inline-expected.png
index 58f925f5..6e8a1c4 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_top_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_width-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_width-expected.png
index 39084ba..5cc8c6d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_width_inline-expected.png
index 12761ab..9de3591 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/border_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/clear-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/clear-expected.png
index 4e76195..32ae336c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/clear-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/clear-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/clear_float-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/clear_float-expected.png
index 17ed55a..497f5fc 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/clear_float-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/clear_float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float-expected.png
index f0fc73e..244cb817 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float_elements_in_series-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float_elements_in_series-expected.png
index df19646..f6d9f81 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float_elements_in_series-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float_elements_in_series-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float_margin-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float_margin-expected.png
index 79c41cb5..eab3e409 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float_margin-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float_margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float_on_text_elements-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float_on_text_elements-expected.png
index 897dd92..6de83e8 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float_on_text_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/float_on_text_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/height-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/height-expected.png
index 27f585d..af0141a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin-expected.png
index 37e79e0..e498950 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_bottom-expected.png
index 6b1b5df..2864cc6d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_bottom_inline-expected.png
index 37865481..d8a5738 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_bottom_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_inline-expected.png
index 84a91b5..6f6d819 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_left-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_left-expected.png
index e6c414e..8cc303e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_left_inline-expected.png
index fcdca9b..201edf5d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_left_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_right-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_right-expected.png
index 2127a2e..c29c6ada 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_right_inline-expected.png
index 169fe1fe9..a8df99b 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_top-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_top-expected.png
index bd492b89..54da32e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_top_inline-expected.png
index 605907e..06dc9de 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_top_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/margin_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding-expected.png
index dda5abb..f88e89e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_bottom-expected.png
index d2c47b3..cd756fc2 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_bottom_inline-expected.png
index ec7400f3..52e2f0b 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_bottom_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_inline-expected.png
index c9a0e64..1a0b20ff 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_left-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_left-expected.png
index d9c5350..a1343d7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_left_inline-expected.png
index bd17bc7..3af3866 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_left_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_right-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_right-expected.png
index dd7922b..5a394503 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_right_inline-expected.png
index 64b1ebc..a0c4536 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_top-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_top-expected.png
index 5dc6318..f4cf45d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_top_inline-expected.png
index 958a292..9dda3b5 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_top_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/padding_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/width-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/width-expected.png
index 093a8b9e..08810dc 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/box_properties/width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/cascade/cascade_order-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/cascade/cascade_order-expected.png
index dd5fab3..f8e0e0e8d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/cascade/cascade_order-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/cascade/cascade_order-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/cascade/important-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/cascade/important-expected.png
index 0c58c74..ba8e9f54 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/cascade/important-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/cascade/important-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/classification/display-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/classification/display-expected.png
index be2308b..eb9b43a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/classification/display-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/classification/display-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style-expected.png
index 8af6f55..512b9f4 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style_image-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style_image-expected.png
index a64cb3185..d501b52 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style_image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style_position-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style_position-expected.png
index cf3bd14..5181ee2 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style_position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style_position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style_type-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style_type-expected.png
index 0b2ec471..2f627fb 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style_type-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/classification/list_style_type-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/classification/white_space-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/classification/white_space-expected.png
index cee3d70..0d9b316 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/classification/white_space-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/classification/white_space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/background_color-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/background_color-expected.png
index 6782702..8500679e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/background_color-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/background_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/background_image-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/background_image-expected.png
index 46b0989..3801e24 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/background_image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/background_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/background_repeat-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/background_repeat-expected.png
index af1364cb3..369727a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/background_repeat-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/background_repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/color-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/color-expected.png
index 53cba51..1329472 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/color-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/color_and_background/color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/conformance/forward_compatible_parsing-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/conformance/forward_compatible_parsing-expected.png
index 9f2d41e..79cef3e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/conformance/forward_compatible_parsing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/conformance/forward_compatible_parsing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font-expected.png
index 6448fda9..ace5161 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_family-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_family-expected.png
index 440a9ee..3273438 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_family-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_family-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_size-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_size-expected.png
index 66b91c9..d82639f0 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_style-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_style-expected.png
index a1daaf4..e986274 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_variant-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_variant-expected.png
index feb15da7..705d728 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_variant-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_variant-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_weight-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_weight-expected.png
index 5dee9b5e..b3e7977 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_weight-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/font_properties/font_weight-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/floating_elements-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/floating_elements-expected.png
index ca1bef1..9212995 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/floating_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/floating_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/height_of_lines-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/height_of_lines-expected.png
index 89f146c..6ae480f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/height_of_lines-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/height_of_lines-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/horizontal_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/horizontal_formatting-expected.png
index c79ca93..535650a4 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/horizontal_formatting-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/horizontal_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/inline_elements-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/inline_elements-expected.png
index b4f0984b..c8db913 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/inline_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/inline_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/replaced_elements-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/replaced_elements-expected.png
index 4a07bd70..29559ed 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/replaced_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/replaced_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/vertical_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/vertical_formatting-expected.png
index 3157dee5..76446176 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/vertical_formatting-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/formatting_model/vertical_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/anchor-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/anchor-expected.png
index fc66848f..7bfeb98 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/anchor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/anchor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/firstletter-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/firstletter-expected.png
index 9efadaaf..197d96c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/firstletter-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/firstletter-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/firstline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/firstline-expected.png
index cbb0334..652e3aa 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/firstline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/firstline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/multiple_pseudo_elements-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/multiple_pseudo_elements-expected.png
index 8bcc5127..83adb0f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/multiple_pseudo_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/multiple_pseudo_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/pseudo_elements_in_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/pseudo_elements_in_selectors-expected.png
index 8eb7716a..d99f30afc 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/pseudo_elements_in_selectors-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/pseudo/pseudo_elements_in_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/letter_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/letter_spacing-expected.png
index 576b99d..65c1dca 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/letter_spacing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/letter_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/line_height-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/line_height-expected.png
index 4539f37..af615b2b 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/line_height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/line_height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_align-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_align-expected.png
index 435c1c4..1e35b2d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_align-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_decoration-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_decoration-expected.png
index 7fd474f..0410709 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_decoration-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_decoration-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_indent-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_indent-expected.png
index af717e6..7a05c850 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_indent-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_indent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_transform-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_transform-expected.png
index fb73520..d1ece7ad 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/text_transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/vertical_align-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/vertical_align-expected.png
index 8e08d880..c2ff1084 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/vertical_align-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/vertical_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/word_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/word_spacing-expected.png
index 140efd6..10e13a7c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/word_spacing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/text_properties/word_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/units/color_units-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/units/color_units-expected.png
index e768313..08df6f1 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/units/color_units-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/units/color_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/units/length_units-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/units/length_units-expected.png
index 92bab55..685fb49 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/units/length_units-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/units/length_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css1/units/percentage_units-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css1/units/percentage_units-expected.png
index c77e636..16f90a3 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css1/units/percentage_units-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css1/units/percentage_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-00-a-ag-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-00-a-ag-expected.png
index 66f181c5..741a908 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-00-a-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-00-a-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-02-d-agi-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-02-d-agi-expected.png
index 97444fe4..5f4d81c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-02-d-agi-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-02-d-agi-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-03-d-agi-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-03-d-agi-expected.png
index 7d9282f..83ac5a0 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-03-d-agi-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-03-d-agi-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-04-d-agi-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-04-d-agi-expected.png
index f4ecf05f6..bafb6cc4 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-04-d-agi-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c544-valgn-04-d-agi-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c548-ln-ht-03-d-ag-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c548-ln-ht-03-d-ag-expected.png
index 2d2b493..4d1a7bc1 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c548-ln-ht-03-d-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t100801-c548-ln-ht-03-d-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-00-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-00-c-ag-expected.png
index 147f167..479c180 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-00-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-00-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-01-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-01-c-ag-expected.png
index 147f167..479c180 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-01-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-01-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-02-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-02-c-ag-expected.png
index a80e3dbb..289b0fff 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-02-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-02-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-03-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-03-c-ag-expected.png
index 147f167..155c6bc 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-03-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-03-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-04-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-04-c-ag-expected.png
index 147f167..a7515c7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-04-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-04-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-05-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-05-c-ag-expected.png
index 147f167..5fe1c594 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-05-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t140201-c534-bgreps-05-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t1605-c545-txttrans-00-b-ag-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t1605-c545-txttrans-00-b-ag-expected.png
index fad780c..204489d5 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css2.1/t1605-c545-txttrans-00-b-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css2.1/t1605-c545-txttrans-00-b-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css3/blending/background-blend-mode-tiled-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css3/blending/background-blend-mode-tiled-gradient-expected.png
index 3b75e0b..9544359 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css3/blending/background-blend-mode-tiled-gradient-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css3/blending/background-blend-mode-tiled-gradient-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css3/masking/mask-luminance-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css3/masking/mask-luminance-gradient-expected.png
new file mode 100644
index 0000000..1f638319
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/css3/masking/mask-luminance-gradient-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/css3/masking/mask-repeat-space-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/css3/masking/mask-repeat-space-border-expected.png
index a6775fa..0ccb92bf 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/css3/masking/mask-repeat-space-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/css3/masking/mask-repeat-space-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/background-repeat-with-background-color-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/background-repeat-with-background-color-expected.png
deleted file mode 100644
index a0567ed..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/background-repeat-with-background-color-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/background-svg-scaling-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/background-svg-scaling-expected.png
deleted file mode 100644
index e43aef8..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/background-svg-scaling-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/repeat/negative-offset-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/repeat/negative-offset-repeat-expected.png
index 4b9315c..bb290c3 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/repeat/negative-offset-repeat-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/repeat/negative-offset-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png
index fccbbcc..95298b0c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/size/backgroundSize15-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/size/backgroundSize15-expected.png
deleted file mode 100644
index e8d23a2..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/backgrounds/size/backgroundSize15-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-border-radius-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-border-radius-expected.png
index e95ab05..c1de92e4 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-border-radius-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-border-radius-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-outset-split-inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-outset-split-inline-expected.png
deleted file mode 100644
index 4559c162..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-outset-split-inline-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-scaled-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-scaled-gradient-expected.png
deleted file mode 100644
index 3e765e93..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/border-image-scaled-gradient-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/scaled-border-image-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/scaled-border-image-expected.png
index e44ad85..4d04330d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/borders/scaled-border-image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/borders/scaled-border-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/canvas/image-object-in-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/canvas/image-object-in-canvas-expected.png
index 7a70c05..fd50afb 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/canvas/image-object-in-canvas-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/canvas/image-object-in-canvas-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/canvas/patternfill-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/canvas/patternfill-repeat-expected.png
new file mode 100644
index 0000000..54e0a20
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/canvas/patternfill-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/canvas/patternfill-repeat-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/canvas/patternfill-repeat-expected.txt
new file mode 100644
index 0000000..479b43d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/canvas/patternfill-repeat-expected.txt
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x469
+  LayoutBlockFlow {HTML} at (0,0) size 800x469
+    LayoutBlockFlow {BODY} at (8,16) size 784x437
+      LayoutBlockFlow {P} at (0,0) size 784x80
+        LayoutText {#text} at (0,0) size 772x79
+          text run at (0,0) width 750: "There should be one big square below containing four squares. Top left square should be filled with 3 rows of 2 and bit"
+          text run at (0,20) width 772: "Apple images. Top right square should be 2 and a bit rows with one Apple image column along the left edge of the square."
+          text run at (0,40) width 764: "Bottom left square should be one row with three Apple images along the top of the square. Bottom right square should be"
+          text run at (0,60) width 220: "one Apple image in top left corner."
+      LayoutBlockFlow {P} at (0,96) size 784x341
+layer at (8,112) size 336x336
+  LayoutHTMLCanvas {CANVAS} at (0,0) size 336x336 [border: (3px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/css/background-image-with-baseurl-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/css/background-image-with-baseurl-expected.png
index e2864755..f599313 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/css/background-image-with-baseurl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/css/background-image-with-baseurl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/css/import_with_baseurl-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/css/import_with_baseurl-expected.png
index e2864755..f599313 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/css/import_with_baseurl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/css/import_with_baseurl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/css/text-overflow-ellipsis-multiple-shadows-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/css/text-overflow-ellipsis-multiple-shadows-expected.png
new file mode 100644
index 0000000..69cb57a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/css/text-overflow-ellipsis-multiple-shadows-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
index 28e21e4..45bf46d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
index e5c16e1..16cf4e74 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
index daef4a126..61dfabd6 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
index 9d757eb..c18cbf3 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
index 01402175..8ebd418f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
index 9ff203c..9a51286 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
index 9c01393d..9081eef 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
index 44a2bcb..51b406c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
index 4d26086..b2d0432 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
index d46fddd..bb43b217 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-expected.png
index c02f212..483fed6 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
index 4f03116..785a3f3 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-expected.png
index c51bf50..c47ef13d5 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
index 9f1eebb..2afda91 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/search/search-appearance-basic-expected.png
index d90961be..dd22b2e4 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/search/search-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/search/search-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png
index 32616bf66..09d6f3b 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/listbox-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/menulist-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/menulist-appearance-basic-expected.png
index 50cf102..6c58beb0 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/menulist-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/menulist-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/select-style-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/select-style-expected.png
index a48439a..7de8ee6 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/select-style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/select/select-style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/submit/submit-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/submit/submit-appearance-basic-expected.png
index 57a19e0..eb55917 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/submit/submit-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/submit/submit-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/input-appearance-bkcolor-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/input-appearance-bkcolor-expected.png
index ae2a30c..40b4baee 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/input-appearance-bkcolor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/input-appearance-bkcolor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/text-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/text-appearance-basic-expected.png
index 1c8ce2d..cde9a59 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/text-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/text/text-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/textarea/textarea-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/textarea/textarea-appearance-basic-expected.png
index b1fd6e3..f6bfdbe 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/forms/textarea/textarea-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/forms/textarea/textarea-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/conic-gradient-out-of-range-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/conic-gradient-out-of-range-expected.png
index c98807a..2f7e1bf 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/conic-gradient-out-of-range-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/conic-gradient-out-of-range-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/conic-gradient-positioning-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/conic-gradient-positioning-expected.png
index 43c096b8..ddc2248 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/conic-gradient-positioning-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/conic-gradient-positioning-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/crash-on-zero-radius-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/crash-on-zero-radius-expected.png
index a3878b0..d5d87adb 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/crash-on-zero-radius-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/crash-on-zero-radius-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/simple-gradients-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/simple-gradients-expected.png
index 60ce8ab..3d5e9dc 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/simple-gradients-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/simple-gradients-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/unprefixed-linear-gradients-color-hints-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/unprefixed-linear-gradients-color-hints-expected.png
deleted file mode 100644
index e800143f..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/unprefixed-linear-gradients-color-hints-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/unprefixed-repeating-gradient-color-hint-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/unprefixed-repeating-gradient-color-hint-expected.png
index e4438714..afe09d8 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/unprefixed-repeating-gradient-color-hint-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/gradients/unprefixed-repeating-gradient-color-hint-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/overflow-with-local-background-attachment-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/overflow-with-local-background-attachment-expected.png
index 293ff60..8bf78d2 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/overflow-with-local-background-attachment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/overflow-with-local-background-attachment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index 2546b77..104f478 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-expected.png
index 15a91c49..43890f66 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-collapsed-border-expected.png
index 95393712..db2cef5a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index e760402..d43998e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-expected.png
index 55bb5e3..bef3ff2 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index 12ab046e..3d1d26a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-expected.png
index f79ae8ade..0a9935ba 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-expected.png
index cd74901..fa9f409 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index b1d2d18..b798e9d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-expected.png
index 9911e6b..854f81b9 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index ffdf3a1..da0bd69 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-expected.png
index 3263ca0d..5e9a2a7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/tbody-background-image-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/tbody-background-image-expected.png
index 5c16b77..30772a8 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/table/tbody-background-image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/tbody-background-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/table/tbody-background-image-repeat-x-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/table/tbody-background-image-repeat-x-expected.png
new file mode 100644
index 0000000..31d3d2f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/table/tbody-background-image-repeat-x-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/border-image-vertical-lr-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/border-image-vertical-lr-expected.png
deleted file mode 100644
index d159a8a4..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/border-image-vertical-lr-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/border-image-vertical-rl-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/border-image-vertical-rl-expected.png
deleted file mode 100644
index 9416c60..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/writing-mode/border-image-vertical-rl-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/linux/http/tests/misc/slow-loading-image-in-pattern-expected.png
index 88e96ae..caa75ef 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/http/tests/misc/slow-loading-image-in-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/http/tests/misc/slow-loading-image-in-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png
index 9a7f55c..7add7db 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background-repeat-space-padding-box-expected.png b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background-repeat-space-padding-box-expected.png
index c05cb04..8180d54 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background-repeat-space-padding-box-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background-repeat-space-padding-box-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background_repeat_space_border_box-expected.png b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background_repeat_space_border_box-expected.png
index d6e9d01..790bbe73 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background_repeat_space_border_box-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background_repeat_space_border_box-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png
index 0cc7f6e5c..63b9ab1 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-clip-text-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-clip-text-expected.png
index 12bc6570..0854a6f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-clip-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-clip-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-image-space-expected.png
index c5d0b0f0..c1ba2de 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-image-space-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-background-image-space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-group-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-group-expected.png
index 61f2f036..54df53f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-expected.png
index 13240f5..2dabcc9 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/images/color-profile-svg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/linux/images/cross-fade-background-size-expected.png
index 11fcc98..82f03761 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/images/cross-fade-background-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/images/cross-fade-background-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/overflow/fixed-background-scroll-window-expected.png b/third_party/WebKit/LayoutTests/platform/linux/paint/overflow/fixed-background-scroll-window-expected.png
new file mode 100644
index 0000000..abd35e6e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/paint/overflow/fixed-background-scroll-window-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/paint/overflow/fixed-background-scroll-window-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/paint/overflow/fixed-background-scroll-window-expected.txt
new file mode 100644
index 0000000..6b1433ef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/paint/overflow/fixed-background-scroll-window-expected.txt
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600 scrollY 1000.00 scrollHeight 4016
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x4016 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x4016
+    LayoutBlockFlow {BODY} at (8,8) size 784x4000
+layer at (8,1116) size 653x20 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutBlockFlow (positioned) {P} at (8,1116) size 653x20
+    LayoutText {#text} at (0,0) size 653x19
+      text run at (0,0) width 653: "Tests painting of fixed background content in scrolled container. Passes if the background doesn't scroll."
+scrolled to 0,1000
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png
index 5000335..c18c20d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/pservers-pattern-04-f-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/pservers-pattern-04-f-expected.png
index 5c19bac..8e7c9ebb 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/pservers-pattern-04-f-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1-SE/pservers-pattern-04-f-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/animate-elem-36-t-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/animate-elem-36-t-expected.png
index c36621d..17bf1ce6 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/animate-elem-36-t-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/animate-elem-36-t-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-units-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-units-01-b-expected.png
index e194904..d2126364 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-units-01-b-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/W3C-SVG-1.1/coords-units-01-b-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-expected.png
index 5e7bbf7..e4b4c7b 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-positioned-objects-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-positioned-objects-expected.png
index fdeab0ae..9a0c17c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-positioned-objects-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/paints/patternRegions-positioned-objects-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textDecoration-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textDecoration-expected.png
index 52459de..04bec2df 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textDecoration-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/batik/text/textDecoration-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/canvas/canvas-default-object-sizing-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/canvas/canvas-default-object-sizing-expected.png
deleted file mode 100644
index 3491a4c..0000000
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/canvas/canvas-default-object-sizing-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/canvas/canvas-pattern-svg-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/canvas/canvas-pattern-svg-expected.png
index 171a963..4df6e30 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/canvas/canvas-pattern-svg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/canvas/canvas-pattern-svg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/masking-clipping-hidpi-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/masking-clipping-hidpi-expected.png
index 5692896..4ee6e116 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/masking-clipping-hidpi-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/masking-clipping-hidpi-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/pattern-cycle-detection-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/pattern-cycle-detection-expected.png
index 5d06cd8b..39cb33f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/pattern-cycle-detection-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/pattern-cycle-detection-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/pattern-deep-referencing-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/pattern-deep-referencing-expected.png
index b7fad1e..c10edfc39 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/pattern-deep-referencing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/pattern-deep-referencing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/pattern-incorrect-tiling-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/pattern-incorrect-tiling-expected.png
index 3ccccc6..c1e62caa 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/pattern-incorrect-tiling-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/pattern-incorrect-tiling-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/stroked-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/stroked-pattern-expected.png
index 60247c4..5b4f0bce 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/stroked-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/stroked-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/transformed-text-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/transformed-text-pattern-expected.png
new file mode 100644
index 0000000..20aea31
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/transformed-text-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/transformed-text-pattern-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/transformed-text-pattern-expected.txt
new file mode 100644
index 0000000..f467ac2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/transformed-text-pattern-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x241
+  LayoutBlockFlow {HTML} at (0,0) size 800x241
+    LayoutBlockFlow {BODY} at (8,8) size 784x225
+      LayoutText {#text} at (0,0) size 320x19
+        text run at (0,0) width 320: "This test passes if there is an A and a green square."
+      LayoutBR {BR} at (320,0) size 0x19
+      LayoutSVGRoot {svg} at (0,20) size 200x200
+        LayoutSVGHiddenContainer {defs} at (0,0) size 0x0
+          LayoutSVGResourcePattern {pattern} [id="pattern"] [patternUnits=userSpaceOnUse] [patternContentUnits=userSpaceOnUse] [patternTransform={m=((10.00,0.00)(0.00,10.00)) t=(0.00,0.00)}]
+            LayoutSVGContainer {g} at (0,40) size 100x70 [transform={m=((0.10,0.00)(0.00,0.10)) t=(0.00,0.00)}]
+              LayoutSVGRect {rect} at (55,55) size 45x45 [fill={[type=SOLID] [color=#008000]}] [x=55.00] [y=55.00] [width=45.00] [height=45.00]
+              LayoutSVGText {text} at (0,40) size 50x70 contains 1 chunk(s)
+                LayoutSVGInlineText {#text} at (0,40) size 50x70
+                  chunk 1 text run 1 at (0.00,100.00) startOffset 0 endOffset 1 width 40.00: "A"
+        LayoutSVGRect {rect} at (0,0) size 400x200 [fill={[type=PATTERN] [id="pattern"]}] [x=0.00] [y=0.00] [width=400.00] [height=200.00]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/use-on-symbol-inside-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/use-on-symbol-inside-pattern-expected.png
index 5a6e42a8..ce933b71 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/custom/use-on-symbol-inside-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/custom/use-on-symbol-inside-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/filters/feImage-preserveAspectRatio-all-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/filters/feImage-preserveAspectRatio-all-expected.png
index e67db00f..4a3d90e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/filters/feImage-preserveAspectRatio-all-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/filters/feImage-preserveAspectRatio-all-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-decorations-in-scaled-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-decorations-in-scaled-pattern-expected.png
index bb2efe9..8b36dadd 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-decorations-in-scaled-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/text/text-decorations-in-scaled-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/transformed-text-fill-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/transformed-text-fill-pattern-expected.png
new file mode 100644
index 0000000..9a1c5cb6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/svg/transforms/transformed-text-fill-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1067-1-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1067-1-expected.png
index 6d18490..8d570a4 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1067-1-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1067-1-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug12008-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug12008-expected.png
index c7c1698..fdd146d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug12008-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug12008-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1296-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1296-expected.png
index 01f579a8..d98febe3f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1296-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1296-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1430-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1430-expected.png
index 4f487e8..abaa945 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1430-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla/bugs/bug1430-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/core/backgrounds-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/core/backgrounds-expected.png
index 03ae63da..24b396b 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/core/backgrounds-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/core/backgrounds-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index e11c44f..928e1eab 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/other/test4-expected.png b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/other/test4-expected.png
index 96d89a3..b78d344f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/other/test4-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/tables/mozilla_expected_failures/other/test4-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/image-object-in-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/image-object-in-canvas-expected.png
index c0ebe97..c93f73f0 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/image-object-in-canvas-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/image-object-in-canvas-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.png
new file mode 100644
index 0000000..54e0a20
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.txt
new file mode 100644
index 0000000..479b43d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.txt
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x469
+  LayoutBlockFlow {HTML} at (0,0) size 800x469
+    LayoutBlockFlow {BODY} at (8,16) size 784x437
+      LayoutBlockFlow {P} at (0,0) size 784x80
+        LayoutText {#text} at (0,0) size 772x79
+          text run at (0,0) width 750: "There should be one big square below containing four squares. Top left square should be filled with 3 rows of 2 and bit"
+          text run at (0,20) width 772: "Apple images. Top right square should be 2 and a bit rows with one Apple image column along the left edge of the square."
+          text run at (0,40) width 764: "Bottom left square should be one row with three Apple images along the top of the square. Bottom right square should be"
+          text run at (0,60) width 220: "one Apple image in top left corner."
+      LayoutBlockFlow {P} at (0,96) size 784x341
+layer at (8,112) size 336x336
+  LayoutHTMLCanvas {CANVAS} at (0,0) size 336x336 [border: (3px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png
index 8ec4a0d..4816f517 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
index 7b65507..5e02c78 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png
index 51f8501..c53509c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-group-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-group-expected.png
index f32fb4b..e0bce7f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-svg-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-svg-expected.png
index 9ee60756..150ce0e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-svg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/color-profile-svg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/cross-fade-background-size-expected.png
index d310499..564f94f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/cross-fade-background-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/cross-fade-background-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png
new file mode 100644
index 0000000..2addd3ee
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/patternfill-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/patternfill-repeat-expected.png
new file mode 100644
index 0000000..04ca244
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/patternfill-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/patternfill-repeat-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/patternfill-repeat-expected.txt
new file mode 100644
index 0000000..479b43d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/gpu/fast/canvas/patternfill-repeat-expected.txt
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x469
+  LayoutBlockFlow {HTML} at (0,0) size 800x469
+    LayoutBlockFlow {BODY} at (8,16) size 784x437
+      LayoutBlockFlow {P} at (0,0) size 784x80
+        LayoutText {#text} at (0,0) size 772x79
+          text run at (0,0) width 750: "There should be one big square below containing four squares. Top left square should be filled with 3 rows of 2 and bit"
+          text run at (0,20) width 772: "Apple images. Top right square should be 2 and a bit rows with one Apple image column along the left edge of the square."
+          text run at (0,40) width 764: "Bottom left square should be one row with three Apple images along the top of the square. Bottom right square should be"
+          text run at (0,60) width 220: "one Apple image in top left corner."
+      LayoutBlockFlow {P} at (0,96) size 784x341
+layer at (8,112) size 336x336
+  LayoutHTMLCanvas {CANVAS} at (0,0) size 336x336 [border: (3px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/comments-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/comments-expected.png
index 23e7fa2..875a1dbc 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/comments-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/comments-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/containment-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/containment-expected.png
index 94d55899..5e0a8d1d0 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/containment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/containment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/contextual_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/contextual_selectors-expected.png
new file mode 100644
index 0000000..6403012
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/contextual_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/grouping-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/grouping-expected.png
new file mode 100644
index 0000000..3025527f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/grouping-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/id_as_selector-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/id_as_selector-expected.png
new file mode 100644
index 0000000..3676b02
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/id_as_selector-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/inheritance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/inheritance-expected.png
index 8afc076b..d75ae9f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/inheritance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/basic/inheritance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border-expected.png
index 662f8b08..39b3e89 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png
index fd606fa..b2b486e4 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_bottom_inline-expected.png
new file mode 100644
index 0000000..56bc31b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png
index 3682aeb6..8f463b2 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_bottom_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_bottom_width_inline-expected.png
new file mode 100644
index 0000000..f084174
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_bottom_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_color-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_color-expected.png
new file mode 100644
index 0000000..9bda7de
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_color_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_color_inline-expected.png
new file mode 100644
index 0000000..d5d5734
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_color_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_inline-expected.png
new file mode 100644
index 0000000..fd2fa92
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_left-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_left-expected.png
index 801d4af..d1b0593 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_left_inline-expected.png
new file mode 100644
index 0000000..d2e2a18
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png
index e891fbb..0f87bc8 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_left_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_left_width_inline-expected.png
new file mode 100644
index 0000000..3880f49
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_left_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_right-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_right-expected.png
new file mode 100644
index 0000000..a6a8b0b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png
new file mode 100644
index 0000000..aa7a52f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png
index 556a3db..25ee29b 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_right_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_right_width_inline-expected.png
new file mode 100644
index 0000000..3978696
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_right_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_style-expected.png
index 5af001f..1da1b49 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png
index a6816bd0..0230695 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_top-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_top-expected.png
index 6f92c67..86ea8a8 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_top_inline-expected.png
new file mode 100644
index 0000000..8a0935ec
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png
index 8a3c921..7e8a215 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_top_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_top_width_inline-expected.png
new file mode 100644
index 0000000..6e8a1c4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_top_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_width-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_width-expected.png
index 39084ba..5cc8c6d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_width_inline-expected.png
new file mode 100644
index 0000000..9de3591
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/border_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/clear-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/clear-expected.png
index 4e76195..32ae336c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/clear-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/clear-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/clear_float-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/clear_float-expected.png
index 17ed55a..497f5fc 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/clear_float-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/clear_float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/float-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/float-expected.png
new file mode 100644
index 0000000..244cb817
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png
index df19646..f6d9f81 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/float_margin-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/float_margin-expected.png
new file mode 100644
index 0000000..eab3e409
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/float_margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/float_on_text_elements-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/float_on_text_elements-expected.png
new file mode 100644
index 0000000..6de83e8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/float_on_text_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/height-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/height-expected.png
index 27f585d..af0141a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin-expected.png
new file mode 100644
index 0000000..e498950
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_bottom-expected.png
new file mode 100644
index 0000000..2864cc6d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_bottom_inline-expected.png
new file mode 100644
index 0000000..d8a5738
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png
index 84a91b5..6f6d819 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_left-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_left-expected.png
index e6c414e..8cc303e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_left_inline-expected.png
new file mode 100644
index 0000000..201edf5d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_right-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_right-expected.png
index 2127a2e..c29c6ada 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_right_inline-expected.png
new file mode 100644
index 0000000..a8df99b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_top-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_top-expected.png
new file mode 100644
index 0000000..54da32e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_top_inline-expected.png
new file mode 100644
index 0000000..06dc9de
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/margin_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding-expected.png
new file mode 100644
index 0000000..f88e89e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_bottom-expected.png
new file mode 100644
index 0000000..cd756fc2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_bottom_inline-expected.png
new file mode 100644
index 0000000..52e2f0b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png
index c9a0e64..1a0b20ff 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_left-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_left-expected.png
index d9c5350..a1343d7 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_left_inline-expected.png
new file mode 100644
index 0000000..3af3866
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_right-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_right-expected.png
new file mode 100644
index 0000000..5a394503
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_right_inline-expected.png
new file mode 100644
index 0000000..a0c4536
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_top-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_top-expected.png
new file mode 100644
index 0000000..f4cf45d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_top_inline-expected.png
new file mode 100644
index 0000000..9dda3b5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/padding_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/width-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/width-expected.png
new file mode 100644
index 0000000..08810dc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/box_properties/width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/cascade/cascade_order-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/cascade/cascade_order-expected.png
index dd5fab3..f8e0e0e8d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/cascade/cascade_order-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/cascade/cascade_order-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/cascade/important-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/cascade/important-expected.png
new file mode 100644
index 0000000..ba8e9f54
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/cascade/important-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/display-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/display-expected.png
index be2308b..eb9b43a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/display-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/display-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/list_style-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/list_style-expected.png
new file mode 100644
index 0000000..512b9f4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/list_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/list_style_image-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/list_style_image-expected.png
new file mode 100644
index 0000000..d501b52
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/list_style_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/list_style_position-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/list_style_position-expected.png
index cf3bd14..5181ee2 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/list_style_position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/list_style_position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/list_style_type-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/list_style_type-expected.png
new file mode 100644
index 0000000..2f627fb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/list_style_type-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/white_space-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/white_space-expected.png
new file mode 100644
index 0000000..0d9b316
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/classification/white_space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/color_and_background/background_color-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/color_and_background/background_color-expected.png
new file mode 100644
index 0000000..8500679e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/color_and_background/background_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/color_and_background/background_image-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/color_and_background/background_image-expected.png
new file mode 100644
index 0000000..3801e24
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/color_and_background/background_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png
index af1364cb3..369727a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/color_and_background/color-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/color_and_background/color-expected.png
new file mode 100644
index 0000000..1329472
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/color_and_background/color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/conformance/forward_compatible_parsing-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/conformance/forward_compatible_parsing-expected.png
new file mode 100644
index 0000000..79cef3e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/conformance/forward_compatible_parsing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font-expected.png
new file mode 100644
index 0000000..ace5161
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font_family-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font_family-expected.png
new file mode 100644
index 0000000..3273438
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font_family-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font_size-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font_size-expected.png
new file mode 100644
index 0000000..d82639f0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font_size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font_style-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font_style-expected.png
new file mode 100644
index 0000000..e986274
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font_variant-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font_variant-expected.png
new file mode 100644
index 0000000..705d728
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font_variant-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font_weight-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font_weight-expected.png
new file mode 100644
index 0000000..b3e7977
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/font_properties/font_weight-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/floating_elements-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/floating_elements-expected.png
new file mode 100644
index 0000000..9212995
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/floating_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/height_of_lines-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/height_of_lines-expected.png
new file mode 100644
index 0000000..6ae480f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/height_of_lines-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/horizontal_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/horizontal_formatting-expected.png
new file mode 100644
index 0000000..535650a4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/horizontal_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png
index b4f0984b..c8db913 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/replaced_elements-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/replaced_elements-expected.png
new file mode 100644
index 0000000..29559ed
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/replaced_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/vertical_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/vertical_formatting-expected.png
new file mode 100644
index 0000000..76446176
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/formatting_model/vertical_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/anchor-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/anchor-expected.png
index fc66848f..7bfeb98 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/anchor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/anchor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/firstletter-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/firstletter-expected.png
index 9efadaaf..197d96c 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/firstletter-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/firstletter-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/firstline-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/firstline-expected.png
index cbb0334..652e3aa 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/firstline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/firstline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
index 8bcc5127..83adb0f 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/pseudo_elements_in_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/pseudo_elements_in_selectors-expected.png
new file mode 100644
index 0000000..d99f30afc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/pseudo/pseudo_elements_in_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/letter_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/letter_spacing-expected.png
new file mode 100644
index 0000000..65c1dca
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/letter_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/line_height-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/line_height-expected.png
new file mode 100644
index 0000000..af615b2b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/line_height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/text_align-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/text_align-expected.png
new file mode 100644
index 0000000..1e35b2d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/text_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png
index 7fd474f..0410709 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/text_indent-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/text_indent-expected.png
new file mode 100644
index 0000000..7a05c850
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/text_indent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/text_transform-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/text_transform-expected.png
index fb73520..d1ece7ad 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/text_transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/text_transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/vertical_align-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/vertical_align-expected.png
new file mode 100644
index 0000000..c2ff1084
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/vertical_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/word_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/word_spacing-expected.png
new file mode 100644
index 0000000..10e13a7c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/text_properties/word_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/units/color_units-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/units/color_units-expected.png
new file mode 100644
index 0000000..08df6f1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/units/color_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/units/length_units-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/units/length_units-expected.png
new file mode 100644
index 0000000..685fb49
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/units/length_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/units/percentage_units-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/units/percentage_units-expected.png
new file mode 100644
index 0000000..16f90a3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/css1/units/percentage_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index 2546b77..104f478 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
new file mode 100644
index 0000000..43890f66
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
index 95393712..db2cef5a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index e760402..d43998e 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
new file mode 100644
index 0000000..bef3ff2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index 12ab046e..3d1d26a 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
new file mode 100644
index 0000000..0a9935ba
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
new file mode 100644
index 0000000..fa9f409
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index b1d2d18..b798e9d 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
new file mode 100644
index 0000000..854f81b9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index ffdf3a1..da0bd69 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
new file mode 100644
index 0000000..5e9a2a7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/tbody-background-image-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/tbody-background-image-expected.png
new file mode 100644
index 0000000..30772a8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/tbody-background-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/tbody-background-image-repeat-x-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/tbody-background-image-repeat-x-expected.png
new file mode 100644
index 0000000..31d3d2f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/fast/table/tbody-background-image-repeat-x-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png
new file mode 100644
index 0000000..caa75ef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/off-main-thread-fetch/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/off-main-thread-fetch/http/tests/misc/slow-loading-image-in-pattern-expected.png
new file mode 100644
index 0000000..caa75ef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/off-main-thread-fetch/http/tests/misc/slow-loading-image-in-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
index 5a2ea42..40e7958 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png
index 5a2ea42..40e7958 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/comments-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/comments-expected.png
index 69059f5b..ecf71919 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/comments-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/comments-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/containment-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/containment-expected.png
index 7f0f20d5a..a7a15181 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/containment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/containment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/contextual_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/contextual_selectors-expected.png
index 332a918..69e23ba 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/contextual_selectors-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/contextual_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/grouping-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/grouping-expected.png
index 4f4526d..feee1d13 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/grouping-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/grouping-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/id_as_selector-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/id_as_selector-expected.png
index d0e2b372..a4f96949 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/id_as_selector-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/id_as_selector-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/inheritance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/inheritance-expected.png
index 6005d01..2ac056e8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/inheritance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/basic/inheritance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border-expected.png
index a18edef3..9653ffa9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom-expected.png
index 8c97e28..473098a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom_inline-expected.png
index 6d5c804..f8ecad609 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom_width-expected.png
index b49ed61..6a66d4f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom_width_inline-expected.png
index 4342308..be8d25f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_bottom_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_color-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_color-expected.png
index 03354a5..8b6ad5a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_color-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_color_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_color_inline-expected.png
index 557e5fa..53ac4ab 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_color_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_color_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_inline-expected.png
index 523936b1..13f0367 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left-expected.png
index 40e2c01..1378f146 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left_inline-expected.png
index a3aaeaa..32afaf96 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left_width-expected.png
index 57e649a..ad88a6ca 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left_width_inline-expected.png
index 83cb014..f8e1bddd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_left_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right-expected.png
index 247ed16a..dd7e6a9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right_inline-expected.png
index 79505016..f2d8036e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right_width-expected.png
index 9ca89fd..6dec767 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right_width_inline-expected.png
index 49d4a38..87f6ed9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_right_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_style-expected.png
index f4a848c..4dc757f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_style_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_style_inline-expected.png
index 7f11984f..60762dd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_style_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_style_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top-expected.png
index b4367933..40c02510d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top_inline-expected.png
index e6f6d80..0387c00 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top_width-expected.png
index 4f269ce..879a7cc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top_width_inline-expected.png
index 82fa8e2..e9ff19a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_top_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_width-expected.png
index 91f7f83..8ec9bc6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_width_inline-expected.png
index 60a896f..43e3676 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/border_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/clear-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/clear-expected.png
index 286c6ef..a7b739f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/clear-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/clear-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/clear_float-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/clear_float-expected.png
index c9a420e..d7f3d54 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/clear_float-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/clear_float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/float-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/float-expected.png
index b626d1c..24ff7442 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/float-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/float_elements_in_series-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/float_elements_in_series-expected.png
index 8e1a3f39..8da10a46 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/float_elements_in_series-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/float_elements_in_series-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/float_margin-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/float_margin-expected.png
index b0c898b1..c94b541 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/float_margin-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/float_margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/height-expected.png
index 7c577da..b2d31bad 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin-expected.png
index bbd0dcd..ed21412 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_bottom-expected.png
index 80e86c11..a91a002f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_bottom_inline-expected.png
index 4bed312..2af28d70 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_bottom_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_inline-expected.png
index cc35b47..9e307b92 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_left-expected.png
index 68312529..a7d2f1f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_left_inline-expected.png
index 9cf26350..c00d4f2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_left_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_right-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_right-expected.png
index f3bd879..c395e891 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_right_inline-expected.png
index 4e3768f..4baa35b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_top-expected.png
index 70f6e9c6..c204b6b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_top_inline-expected.png
index f7e1ec0f..4ab4b415 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_top_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/margin_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding-expected.png
index 0af2932..fab6c02 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_bottom-expected.png
index 6f8b3176..bada874 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_bottom_inline-expected.png
index 37ff2d1..1db27dab 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_bottom_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_inline-expected.png
index 1d75b80..fdad215 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_left-expected.png
index 32baba0..88eb10d1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_left_inline-expected.png
index 57edf69..4f5aa76 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_left_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_right-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_right-expected.png
index 87a7dcfe..53970e9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_right_inline-expected.png
index 374781c..97b27f68 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_top-expected.png
index 23ae134a..5b7e054 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_top_inline-expected.png
index 356f3ef..753b886 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_top_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/padding_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/width-expected.png
index 41072bb..9f4ab3158 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/box_properties/width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/cascade/cascade_order-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/cascade/cascade_order-expected.png
index 7a9c602..9a613f4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/cascade/cascade_order-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/cascade/cascade_order-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/cascade/important-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/cascade/important-expected.png
index eabc354..b3e7dbd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/cascade/important-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/cascade/important-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/display-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/display-expected.png
index 725d0d5..d4f3f41 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/display-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/display-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style-expected.png
index 0d38fcb..c886e5c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style_image-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style_image-expected.png
index c362ac5..ab536c5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style_image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style_position-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style_position-expected.png
index 81130c79a..704c62f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style_position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style_position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style_type-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style_type-expected.png
index e4a958e..1832546f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style_type-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/list_style_type-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/white_space-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/white_space-expected.png
index 537fa16eb..b9fd70a8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/white_space-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/classification/white_space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/background_color-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/background_color-expected.png
index dff0515..2125b1f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/background_color-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/background_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/background_image-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/background_image-expected.png
index a16a9c41..290ea39a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/background_image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/background_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/background_repeat-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/background_repeat-expected.png
index 26e2550..e117c95 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/background_repeat-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/background_repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/color-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/color-expected.png
index 1ad1a880..2165dec 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/color-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/color_and_background/color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/conformance/forward_compatible_parsing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/conformance/forward_compatible_parsing-expected.png
index 9bbc7ca..b040a6c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/conformance/forward_compatible_parsing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/conformance/forward_compatible_parsing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_family-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_family-expected.png
index e5a719c..90f88ef 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_family-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_family-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_size-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_size-expected.png
index bcd4949..431087f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_style-expected.png
index aa7abec..aa7ddc39 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_variant-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_variant-expected.png
index 778bc93..fb094a57 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_variant-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_variant-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_weight-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_weight-expected.png
index 2903922..c87b6f3e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_weight-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/font_properties/font_weight-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/floating_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/floating_elements-expected.png
index d8e43160..4d6ecd4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/floating_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/floating_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/height_of_lines-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/height_of_lines-expected.png
index a8c58bb..436f90d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/height_of_lines-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/height_of_lines-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/inline_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/inline_elements-expected.png
index 81df0a3e..81d3ba23 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/inline_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/inline_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/replaced_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/replaced_elements-expected.png
index cdd236d3..114b604 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/replaced_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/replaced_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/vertical_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/vertical_formatting-expected.png
index d2915a12..a7f20de 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/vertical_formatting-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/formatting_model/vertical_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/anchor-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/anchor-expected.png
index 1d27ef9..99e6778 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/anchor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/anchor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/firstletter-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/firstletter-expected.png
index 9e93849..1270a1e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/firstletter-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/firstletter-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/firstline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/firstline-expected.png
index 3f71d27..730b457 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/firstline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/firstline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/multiple_pseudo_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/multiple_pseudo_elements-expected.png
index ade7475d..cfb7ade2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/multiple_pseudo_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/multiple_pseudo_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/pseudo_elements_in_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/pseudo_elements_in_selectors-expected.png
index c5adb610..ee0258bc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/pseudo_elements_in_selectors-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/pseudo/pseudo_elements_in_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/letter_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/letter_spacing-expected.png
index c8f9e6f..699f624 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/letter_spacing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/letter_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/line_height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/line_height-expected.png
index 4fce89f..1e9db066 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/line_height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/line_height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_align-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_align-expected.png
index 0445289..2c13865 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_align-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_decoration-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_decoration-expected.png
index d3b0038..e3e89ad 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_decoration-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_decoration-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_indent-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_indent-expected.png
index 1107330..074969e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_indent-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_indent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_transform-expected.png
index 94b8c155..7ba621a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/text_transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/vertical_align-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/vertical_align-expected.png
index 720ee85..e56cfc2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/vertical_align-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/vertical_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/word_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/word_spacing-expected.png
index 27f8304..bbc7939 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/word_spacing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/text_properties/word_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/units/color_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/units/color_units-expected.png
index c8b12cb1..e19dcf5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/units/color_units-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/units/color_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/units/length_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/units/length_units-expected.png
index eb7eb7d7..d578c81e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/units/length_units-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/units/length_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/units/percentage_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/units/percentage_units-expected.png
index e209082..bf6f9a0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/units/percentage_units-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/css1/units/percentage_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
index 450f17e..dc1aa24 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
index 0a4e408..fc7d5e0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
index 7d7f441c..b47f2cb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
index 17f2365b..7f967d7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
index 0eefdc6..31ad48a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
index 44593843..fcaffdc3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
index 3f877a9..28291d2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
index 1b34889..4ddf36b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
index 0e827bf..dbdc4a5a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
index 7809024..b64748d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-expected.png
index ea4fa42..5bfe693 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
index 88df61c..47f2ffa 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-expected.png
index f8bcef9..6baa2e0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
index 18bba09..8003bde5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-appearance-basic-expected.png
index f136436d..bb3df4c2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/search/search-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/listbox-appearance-basic-expected.png
index 0a4bc1bc7..e2989919 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/listbox-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/listbox-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-style-expected.png
index 0809069..462226a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/select/select-style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/submit/submit-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/submit/submit-appearance-basic-expected.png
index 127fc2d..988a1eb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/submit/submit-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/submit/submit-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/input-appearance-bkcolor-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/input-appearance-bkcolor-expected.png
index d889b58..16bb934 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/input-appearance-bkcolor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/input-appearance-bkcolor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/text-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/text-appearance-basic-expected.png
index 9a5e333..3f2212a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/text-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/text/text-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/textarea/textarea-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/textarea/textarea-appearance-basic-expected.png
index 1000e67d..3d108cb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/textarea/textarea-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/forms/textarea/textarea-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index 1bdb0722..2c474e28 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-expected.png
index b4afcc6..28dc1f8f9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-collapsed-border-expected.png
index 6e83d0c..e2a5565 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index a7696f68..354cfb6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-expected.png
index d6da6f2..0a4b027 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index 8a46df7..9a9a14c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-expected.png
index 089c050..8b3cb5ba 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-expected.png
index e72d9cc..f766b078 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index f8f7b99..9468d57 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-expected.png
index 910fd72..2f06ac1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index 121039ab..9832aff 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-expected.png
index 362a960..fed5f54c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index 1f5aaad..9d386da 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/comments-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/comments-expected.png
index 69059f5b..ecf71919 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/comments-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/comments-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/containment-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/containment-expected.png
index 7f0f20d5a..a7a15181 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/containment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/containment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/contextual_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/contextual_selectors-expected.png
new file mode 100644
index 0000000..69e23ba
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/contextual_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/grouping-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/grouping-expected.png
new file mode 100644
index 0000000..feee1d13
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/grouping-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/id_as_selector-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/id_as_selector-expected.png
new file mode 100644
index 0000000..a4f96949
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/id_as_selector-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/inheritance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/inheritance-expected.png
index 6005d01..2ac056e8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/inheritance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/basic/inheritance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border-expected.png
index a18edef3..9653ffa9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png
index 8c97e28..473098a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_bottom_inline-expected.png
new file mode 100644
index 0000000..f8ecad609
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png
index b49ed61..6a66d4f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_bottom_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_bottom_width_inline-expected.png
new file mode 100644
index 0000000..be8d25f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_bottom_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_color-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_color-expected.png
new file mode 100644
index 0000000..8b6ad5a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_color_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_color_inline-expected.png
new file mode 100644
index 0000000..53ac4ab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_color_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_inline-expected.png
new file mode 100644
index 0000000..13f0367
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_left-expected.png
index 40e2c01..1378f146 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_left_inline-expected.png
new file mode 100644
index 0000000..32afaf96
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png
index 57e649a..ad88a6ca 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_left_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_left_width_inline-expected.png
new file mode 100644
index 0000000..f8e1bddd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_left_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_right-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_right-expected.png
new file mode 100644
index 0000000..dd7e6a9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png
index 79505016..f2d8036e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png
index 9ca89fd..6dec767 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_right_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_right_width_inline-expected.png
new file mode 100644
index 0000000..87f6ed9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_right_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_style-expected.png
index f4a848c..4dc757f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png
index 7f11984f..60762dd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_top-expected.png
index b4367933..40c02510d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_top_inline-expected.png
new file mode 100644
index 0000000..0387c00
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png
index 4f269ce..879a7cc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_top_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_top_width_inline-expected.png
new file mode 100644
index 0000000..e9ff19a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_top_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_width-expected.png
index 91f7f83..8ec9bc6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_width_inline-expected.png
new file mode 100644
index 0000000..43e3676
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/border_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/clear-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/clear-expected.png
index 286c6ef..a7b739f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/clear-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/clear-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/clear_float-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/clear_float-expected.png
index c9a420e..d7f3d54 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/clear_float-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/clear_float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/float-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/float-expected.png
new file mode 100644
index 0000000..24ff7442
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png
index 8e1a3f39..8da10a46 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/float_margin-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/float_margin-expected.png
new file mode 100644
index 0000000..c94b541
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/float_margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/height-expected.png
index 7c577da..b2d31bad 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin-expected.png
new file mode 100644
index 0000000..ed21412
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_bottom-expected.png
new file mode 100644
index 0000000..a91a002f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_bottom_inline-expected.png
new file mode 100644
index 0000000..2af28d70
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png
index cc35b47..9e307b92 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_left-expected.png
index 68312529..a7d2f1f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_left_inline-expected.png
new file mode 100644
index 0000000..c00d4f2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_right-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_right-expected.png
index f3bd879..c395e891 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_right_inline-expected.png
new file mode 100644
index 0000000..4baa35b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_top-expected.png
new file mode 100644
index 0000000..c204b6b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_top_inline-expected.png
new file mode 100644
index 0000000..4ab4b415
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/margin_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding-expected.png
new file mode 100644
index 0000000..fab6c02
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_bottom-expected.png
new file mode 100644
index 0000000..bada874
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_bottom_inline-expected.png
new file mode 100644
index 0000000..1db27dab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png
index 1d75b80..fdad215 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_left-expected.png
index 32baba0..88eb10d1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_left_inline-expected.png
new file mode 100644
index 0000000..4f5aa76
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_right-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_right-expected.png
new file mode 100644
index 0000000..53970e9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_right_inline-expected.png
new file mode 100644
index 0000000..97b27f68
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_top-expected.png
new file mode 100644
index 0000000..5b7e054
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_top_inline-expected.png
new file mode 100644
index 0000000..753b886
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/padding_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/width-expected.png
new file mode 100644
index 0000000..9f4ab3158
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/box_properties/width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/cascade/cascade_order-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/cascade/cascade_order-expected.png
index 7a9c602..9a613f4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/cascade/cascade_order-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/cascade/cascade_order-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/cascade/important-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/cascade/important-expected.png
new file mode 100644
index 0000000..b3e7dbd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/cascade/important-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/display-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/display-expected.png
index 725d0d5..d4f3f41 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/display-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/display-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/list_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/list_style-expected.png
new file mode 100644
index 0000000..c886e5c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/list_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/list_style_image-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/list_style_image-expected.png
new file mode 100644
index 0000000..ab536c5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/list_style_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/list_style_position-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/list_style_position-expected.png
index 81130c79a..704c62f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/list_style_position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/list_style_position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/list_style_type-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/list_style_type-expected.png
new file mode 100644
index 0000000..1832546f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/list_style_type-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/white_space-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/white_space-expected.png
new file mode 100644
index 0000000..b9fd70a8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/classification/white_space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/color_and_background/background_color-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/color_and_background/background_color-expected.png
new file mode 100644
index 0000000..2125b1f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/color_and_background/background_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/color_and_background/background_image-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/color_and_background/background_image-expected.png
new file mode 100644
index 0000000..290ea39a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/color_and_background/background_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png
index 26e2550..e117c95 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/color_and_background/color-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/color_and_background/color-expected.png
new file mode 100644
index 0000000..2165dec
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/color_and_background/color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/conformance/forward_compatible_parsing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/conformance/forward_compatible_parsing-expected.png
new file mode 100644
index 0000000..b040a6c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/conformance/forward_compatible_parsing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/font_properties/font_family-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/font_properties/font_family-expected.png
new file mode 100644
index 0000000..90f88ef
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/font_properties/font_family-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/font_properties/font_size-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/font_properties/font_size-expected.png
new file mode 100644
index 0000000..431087f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/font_properties/font_size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/font_properties/font_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/font_properties/font_style-expected.png
new file mode 100644
index 0000000..aa7ddc39
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/font_properties/font_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/font_properties/font_variant-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/font_properties/font_variant-expected.png
new file mode 100644
index 0000000..fb094a57
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/font_properties/font_variant-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/font_properties/font_weight-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/font_properties/font_weight-expected.png
new file mode 100644
index 0000000..c87b6f3e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/font_properties/font_weight-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/floating_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/floating_elements-expected.png
new file mode 100644
index 0000000..4d6ecd4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/floating_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/height_of_lines-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/height_of_lines-expected.png
new file mode 100644
index 0000000..436f90d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/height_of_lines-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png
index 81df0a3e..81d3ba23 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/replaced_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/replaced_elements-expected.png
new file mode 100644
index 0000000..114b604
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/replaced_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/vertical_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/vertical_formatting-expected.png
new file mode 100644
index 0000000..a7f20de
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/formatting_model/vertical_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/anchor-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/anchor-expected.png
index 1d27ef9..99e6778 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/anchor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/anchor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/firstletter-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/firstletter-expected.png
index 9e93849..1270a1e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/firstletter-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/firstletter-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/firstline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/firstline-expected.png
index 3f71d27..730b457 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/firstline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/firstline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
index ade7475d..cfb7ade2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/pseudo_elements_in_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/pseudo_elements_in_selectors-expected.png
new file mode 100644
index 0000000..ee0258bc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/pseudo/pseudo_elements_in_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/letter_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/letter_spacing-expected.png
new file mode 100644
index 0000000..699f624
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/letter_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/line_height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/line_height-expected.png
new file mode 100644
index 0000000..1e9db066
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/line_height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/text_align-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/text_align-expected.png
new file mode 100644
index 0000000..2c13865
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/text_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png
index d3b0038..e3e89ad 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/text_indent-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/text_indent-expected.png
new file mode 100644
index 0000000..074969e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/text_indent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/text_transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/text_transform-expected.png
index 94b8c155..7ba621a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/text_transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/text_transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/vertical_align-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/vertical_align-expected.png
new file mode 100644
index 0000000..e56cfc2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/vertical_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/word_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/word_spacing-expected.png
new file mode 100644
index 0000000..bbc7939
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/text_properties/word_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/units/color_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/units/color_units-expected.png
new file mode 100644
index 0000000..e19dcf5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/units/color_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/units/length_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/units/length_units-expected.png
new file mode 100644
index 0000000..d578c81e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/units/length_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/units/percentage_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/units/percentage_units-expected.png
new file mode 100644
index 0000000..bf6f9a0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/css1/units/percentage_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index 1bdb0722..2c474e28 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
new file mode 100644
index 0000000..28dc1f8f9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
index 6e83d0c..e2a5565 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index a7696f68..354cfb6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
new file mode 100644
index 0000000..0a4b027
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index 8a46df7..9a9a14c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
new file mode 100644
index 0000000..8b3cb5ba
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
new file mode 100644
index 0000000..f766b078
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index f8f7b99..9468d57 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
new file mode 100644
index 0000000..2f06ac1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index 121039ab..9832aff 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
new file mode 100644
index 0000000..fed5f54c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
index 626129fd..71f7eb97 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
index 12f7fa0..55edbf2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
index cb1ee6d..1c3f7d7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
index f85684e..261240f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
index 3579f562..6850d6e9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
index e865c33..3a3e60e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
index 5256272..c5a941d2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
index 327f34b3..c5658e0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
index 20d474a2..a384cfa 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
index 72f124d..97216bf5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
index 2119aa5..3e445fa 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-expected.png
index eb8b3e09..bd501c6c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
index b13d066..32d6e5c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-expected.png
index e67e941..82793cac 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
index 9105f02f..ca88b6c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-appearance-basic-expected.png
index 136d6126..b3b74f8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/search/search-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-style-expected.png
index 6bf3e1b..ee17ccb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/select/select-style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/submit/submit-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/submit/submit-appearance-basic-expected.png
index cb0412da..6bd6499 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/submit/submit-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/submit/submit-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/text/input-appearance-bkcolor-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/text/input-appearance-bkcolor-expected.png
index 21ed609..d8b7836f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/text/input-appearance-bkcolor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/text/input-appearance-bkcolor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/text/text-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/text/text-appearance-basic-expected.png
index 48beaa39..ac8d6e6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/text/text-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/text/text-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/textarea/textarea-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/textarea/textarea-appearance-basic-expected.png
index fbfb854..76849d0b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/textarea/textarea-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/forms/textarea/textarea-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index e868e424..ad0e230 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-cell-expected.png
index 748a45a89..7fba16e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-collapsed-border-expected.png
index 8bd8a0c5..68059da6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index 111977d..620bdfc6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-expected.png
index 0f42d150..ddf6c64d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index c1dfbc3..7cff2ff 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-group-expected.png
index 8e1bd82..412f67f2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-expected.png
index a28d673..a6ee4c5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index 5dbfbd4..b1facaa 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-expected.png
index afd42dd1..7f2a6d7c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index 820cd47..27c20720 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-group-expected.png
index 37df9296..6ab30b2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index 8a320b3f..b6fe849 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index e868e424..ad0e230 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
new file mode 100644
index 0000000..7fba16e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
index 8bd8a0c5..68059da6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index 111977d..620bdfc6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
new file mode 100644
index 0000000..ddf6c64d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index c1dfbc3..7cff2ff 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
new file mode 100644
index 0000000..412f67f2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
new file mode 100644
index 0000000..a6ee4c5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index 5dbfbd4..b1facaa 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
new file mode 100644
index 0000000..7f2a6d7c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index 820cd47..27c20720 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
new file mode 100644
index 0000000..6ab30b2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
index d5ae38c..97498ed 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.11/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/comments-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/comments-expected.png
index cc8a3367..88bb108 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/comments-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/comments-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/containment-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/containment-expected.png
index 3ef6891..66521817 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/containment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/containment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/contextual_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/contextual_selectors-expected.png
index 06aa4c6..ebaa788 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/contextual_selectors-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/contextual_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/id_as_selector-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/id_as_selector-expected.png
index cd2b0b3..66fc31c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/id_as_selector-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/basic/id_as_selector-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border-expected.png
index 47707bb..ca06ece6e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_bottom-expected.png
index 662ef41..672dc74 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_bottom_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_bottom_width-expected.png
index b767854..68385307 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_bottom_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_bottom_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_left-expected.png
index cc3edf2a..a65a092 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_left_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_left_width-expected.png
index e94af22..f8f9363 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_left_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_left_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_right_inline-expected.png
index 605d8434..0362991 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_right_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_right_width-expected.png
index 75ae04ba..8b918dfd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_right_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_right_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_style-expected.png
index fd046da..7af2f840 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_top-expected.png
index cf59b7e..120bcf8b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_top_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_top_width-expected.png
index c047ecc..f6c8bee4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_top_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_top_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_width-expected.png
index 6d7668e..51b9810 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/border_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/clear-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/clear-expected.png
index 7a95e48..625163c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/clear-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/clear-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/float_elements_in_series-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/float_elements_in_series-expected.png
index 12075ee..867afbe4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/float_elements_in_series-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/float_elements_in_series-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/float_margin-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/float_margin-expected.png
index e107155..018a85c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/float_margin-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/float_margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/float_on_text_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/float_on_text_elements-expected.png
index ace4b553..f142f3cc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/float_on_text_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/float_on_text_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/height-expected.png
index d48dba1..bb27ac7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/margin_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/margin_bottom-expected.png
index 67b0795..d4a90f43 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/margin_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/margin_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/margin_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/margin_left-expected.png
index a98f8ca..691c5e158 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/margin_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/margin_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/margin_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/margin_top-expected.png
index 6fc938f..ebc11eec 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/margin_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/margin_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding-expected.png
index eec6b9cd..59f8728 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_bottom-expected.png
index 3301c2d9..8a7571d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_inline-expected.png
index 2ca90d6..48899c4e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_left-expected.png
index 1066255..b13433b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_right-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_right-expected.png
index 40825a0..468888b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_top-expected.png
index e63f403f..c7a302b6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/padding_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/width-expected.png
index fa139f9..691614e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/box_properties/width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/cascade/cascade_order-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/cascade/cascade_order-expected.png
index 34999e2..a6bdf40 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/cascade/cascade_order-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/cascade/cascade_order-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/classification/display-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/classification/display-expected.png
index d7b38e2..828ac99 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/classification/display-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/classification/display-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/classification/list_style_type-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/classification/list_style_type-expected.png
index 920f4f0..5e0886ba 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/classification/list_style_type-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/classification/list_style_type-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/conformance/forward_compatible_parsing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/conformance/forward_compatible_parsing-expected.png
index 608f856..7c4ac680 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/conformance/forward_compatible_parsing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/conformance/forward_compatible_parsing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font-expected.png
index f6b822b..401a167d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font_family-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font_family-expected.png
index 7813199..cab3436f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font_family-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font_family-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font_size-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font_size-expected.png
index 1623ccc..2aeec65 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font_size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font_size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font_weight-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font_weight-expected.png
index 3bf8725..7944ba9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font_weight-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/font_properties/font_weight-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/floating_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/floating_elements-expected.png
index 056f35c..1b59eb6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/floating_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/floating_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/height_of_lines-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/height_of_lines-expected.png
index 3dbb70a..bd22de2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/height_of_lines-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/height_of_lines-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/inline_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/inline_elements-expected.png
index 4e60076d..b24f927 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/inline_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/inline_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/replaced_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/replaced_elements-expected.png
index 368c633..e04111c75 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/replaced_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/replaced_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/vertical_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/vertical_formatting-expected.png
index bde32737..198811e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/vertical_formatting-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/formatting_model/vertical_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/anchor-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/anchor-expected.png
index b0ed1b4..a04645b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/anchor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/anchor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/firstletter-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/firstletter-expected.png
index 669e39ca..f4263e5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/firstletter-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/firstletter-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/firstline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/firstline-expected.png
index 2e83da8..b9533f9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/firstline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/firstline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/multiple_pseudo_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/multiple_pseudo_elements-expected.png
index 4ab7e61..f23931c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/multiple_pseudo_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/pseudo/multiple_pseudo_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/letter_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/letter_spacing-expected.png
index b7565ba..2ad40a065 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/letter_spacing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/letter_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/line_height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/line_height-expected.png
index 4869f65c..4d22f217 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/line_height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/line_height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/text_decoration-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/text_decoration-expected.png
index 16acd60..7c38daf6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/text_decoration-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/text_decoration-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/text_indent-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/text_indent-expected.png
index 7c83ac8..a677e020 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/text_indent-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/text_indent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/text_transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/text_transform-expected.png
index f2de7672..dadbbeb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/text_transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/text_transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/vertical_align-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/vertical_align-expected.png
index 86062e90..4444237f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/vertical_align-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/vertical_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/word_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/word_spacing-expected.png
index 03bfc9e..7804218 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/word_spacing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/text_properties/word_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/units/color_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/units/color_units-expected.png
index 31b45d7..5920034 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/units/color_units-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/units/color_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/units/length_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/units/length_units-expected.png
index 1064807..ed924e13 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/units/length_units-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css1/units/length_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css3/masking/mask-luminance-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css3/masking/mask-luminance-gradient-expected.png
new file mode 100644
index 0000000..2aa13883
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css3/masking/mask-luminance-gradient-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css3/masking/mask-repeat-space-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css3/masking/mask-repeat-space-border-expected.png
index e47dd643..9962f18 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css3/masking/mask-repeat-space-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/css3/masking/mask-repeat-space-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
index e2ed831..49f45d30 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
index ddebd363..529901c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
index 7dbc333..389c236 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
index f77b2995..a439c02 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
index 6d92ae4..f7d24c8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
index ce929e7..5c5bf77 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
index 7de9b28..de0c9709 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
index cbb8b8e..871b4ed 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
index 358f92d..c37aea6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-expected.png
index 1a0c4f2..1392a0d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
index 9b7fe89..f9b6a356 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-expected.png
index e2adb623..3f43748 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
index 9527bae..63d91401 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/search/search-appearance-basic-expected.png
index 7380d95e..c22cdd50 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/search/search-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/search/search-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/select-style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/select-style-expected.png
index 7c005c00..d802a84a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/select-style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/select/select-style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/submit/submit-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/submit/submit-appearance-basic-expected.png
index cfea5b2..5454d7ea3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/submit/submit-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/submit/submit-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/input-appearance-bkcolor-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/input-appearance-bkcolor-expected.png
index 45abc0c..6cde391 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/input-appearance-bkcolor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/input-appearance-bkcolor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/text-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/text-appearance-basic-expected.png
index c2c72c5..1557583 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/text-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/text/text-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/textarea/textarea-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/textarea/textarea-appearance-basic-expected.png
index 34e01dd..a423eb5e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/textarea/textarea-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/forms/textarea/textarea-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/overflow/overflow-with-local-background-attachment-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/overflow/overflow-with-local-background-attachment-expected.png
index 2c1bca0..608f934 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/overflow/overflow-with-local-background-attachment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/overflow/overflow-with-local-background-attachment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index 11f62af..3b586ed 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-expected.png
index 4de5c23..3c472d1f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-collapsed-border-expected.png
index d95e44f..19d62e5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index 1cf6436..0490ccb5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-expected.png
index 6febfe90..30a968b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index 7ad8c1df..c4d99ae5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-expected.png
index 41833f2f..f6178c8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-expected.png
index 6aa6f72c..5362e746 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index 98a2e8b..a50a4ca3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-expected.png
index 53b2c98..f67665cd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index 48eb25f..3b85bf8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-expected.png
index 17ef097..1ba574fc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png
index 665a03f..f7c9179 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png
index 4116e4f78..2e68d4f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/svg/transforms/transformed-text-fill-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/svg/transforms/transformed-text-fill-pattern-expected.png
new file mode 100644
index 0000000..d8f11bf
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/svg/transforms/transformed-text-fill-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index 879bdd5b..0e97bce 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/other/test4-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/other/test4-expected.png
index a9a5805..3e82073 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/other/test4-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/tables/mozilla_expected_failures/other/test4-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/basic/comments-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/basic/comments-expected.png
index cc8a3367..88bb108 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/basic/comments-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/basic/comments-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/basic/containment-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/basic/containment-expected.png
index 3ef6891..66521817 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/basic/containment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/basic/containment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/basic/contextual_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/basic/contextual_selectors-expected.png
new file mode 100644
index 0000000..ebaa788
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/basic/contextual_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/basic/id_as_selector-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/basic/id_as_selector-expected.png
new file mode 100644
index 0000000..66fc31c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/basic/id_as_selector-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border-expected.png
index 47707bb..ca06ece6e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png
index 662ef41..672dc74 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png
index b767854..68385307 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_left-expected.png
index cc3edf2a..a65a092 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png
index e94af22..f8f9363 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png
index 605d8434..0362991 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png
index 75ae04ba..8b918dfd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_style-expected.png
index fd046da..7af2f840 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_top-expected.png
index cf59b7e..120bcf8b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png
index c047ecc..f6c8bee4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_width-expected.png
index 6d7668e..51b9810 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/border_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/clear-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/clear-expected.png
index 7a95e48..625163c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/clear-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/clear-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png
index 12075ee..867afbe4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/float_margin-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/float_margin-expected.png
new file mode 100644
index 0000000..018a85c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/float_margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/float_on_text_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/float_on_text_elements-expected.png
new file mode 100644
index 0000000..f142f3cc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/float_on_text_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/height-expected.png
index d48dba1..bb27ac7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/margin_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/margin_bottom-expected.png
new file mode 100644
index 0000000..d4a90f43
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/margin_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/margin_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/margin_left-expected.png
index a98f8ca..691c5e158 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/margin_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/margin_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/margin_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/margin_top-expected.png
new file mode 100644
index 0000000..ebc11eec
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/margin_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding-expected.png
new file mode 100644
index 0000000..59f8728
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_bottom-expected.png
new file mode 100644
index 0000000..8a7571d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png
index 2ca90d6..48899c4e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_left-expected.png
index 1066255..b13433b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_right-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_right-expected.png
new file mode 100644
index 0000000..468888b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_top-expected.png
new file mode 100644
index 0000000..c7a302b6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/padding_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/width-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/width-expected.png
new file mode 100644
index 0000000..691614e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/box_properties/width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/cascade/cascade_order-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/cascade/cascade_order-expected.png
index 34999e2..a6bdf40 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/cascade/cascade_order-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/cascade/cascade_order-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/classification/display-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/classification/display-expected.png
index d7b38e2..828ac99 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/classification/display-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/classification/display-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/classification/list_style_type-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/classification/list_style_type-expected.png
new file mode 100644
index 0000000..5e0886ba
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/classification/list_style_type-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/conformance/forward_compatible_parsing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/conformance/forward_compatible_parsing-expected.png
new file mode 100644
index 0000000..7c4ac680
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/conformance/forward_compatible_parsing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/font_properties/font-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/font_properties/font-expected.png
new file mode 100644
index 0000000..401a167d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/font_properties/font-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/font_properties/font_family-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/font_properties/font_family-expected.png
new file mode 100644
index 0000000..cab3436f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/font_properties/font_family-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/font_properties/font_size-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/font_properties/font_size-expected.png
new file mode 100644
index 0000000..2aeec65
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/font_properties/font_size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/font_properties/font_weight-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/font_properties/font_weight-expected.png
new file mode 100644
index 0000000..7944ba9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/font_properties/font_weight-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/floating_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/floating_elements-expected.png
new file mode 100644
index 0000000..1b59eb6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/floating_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/height_of_lines-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/height_of_lines-expected.png
new file mode 100644
index 0000000..bd22de2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/height_of_lines-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png
index 4e60076d..b24f927 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/replaced_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/replaced_elements-expected.png
new file mode 100644
index 0000000..e04111c75
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/replaced_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/vertical_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/vertical_formatting-expected.png
new file mode 100644
index 0000000..198811e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/formatting_model/vertical_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/anchor-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/anchor-expected.png
index b0ed1b4..a04645b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/anchor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/anchor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/firstletter-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/firstletter-expected.png
index 669e39ca..f4263e5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/firstletter-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/firstletter-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/firstline-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/firstline-expected.png
index 2e83da8..b9533f9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/firstline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/firstline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
index 4ab7e61..f23931c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/letter_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/letter_spacing-expected.png
new file mode 100644
index 0000000..2ad40a065
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/letter_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/line_height-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/line_height-expected.png
new file mode 100644
index 0000000..4d22f217
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/line_height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png
index 16acd60..7c38daf6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/text_indent-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/text_indent-expected.png
new file mode 100644
index 0000000..a677e020
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/text_indent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/text_transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/text_transform-expected.png
index f2de7672..dadbbeb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/text_transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/text_transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/vertical_align-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/vertical_align-expected.png
new file mode 100644
index 0000000..4444237f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/vertical_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/word_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/word_spacing-expected.png
new file mode 100644
index 0000000..7804218
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/text_properties/word_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/units/color_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/units/color_units-expected.png
new file mode 100644
index 0000000..5920034
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/units/color_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/units/length_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/units/length_units-expected.png
new file mode 100644
index 0000000..ed924e13
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/css1/units/length_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index 11f62af..3b586ed 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
new file mode 100644
index 0000000..3c472d1f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
index d95e44f..19d62e5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index 1cf6436..0490ccb5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
new file mode 100644
index 0000000..30a968b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index 7ad8c1df..c4d99ae5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
new file mode 100644
index 0000000..f6178c8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
new file mode 100644
index 0000000..5362e746
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index 98a2e8b..a50a4ca3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
new file mode 100644
index 0000000..f67665cd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index 48eb25f..3b85bf8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
new file mode 100644
index 0000000..1ba574fc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
index 6198398..e1fa601 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
index 12f7fa0..55edbf2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
index cb1ee6d..1c3f7d7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
index f85684e..261240f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
index 3579f562..6850d6e9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
index e865c33..3a3e60e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
index 5256272..c5a941d2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
index 327f34b3..c5658e0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
index 20d474a2..a384cfa 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
index 72f124d..97216bf5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
index 2119aa5..3e445fa 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-expected.png
index eb8b3e09..bd501c6c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
index b13d066..32d6e5c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-expected.png
index e67e941..82793cac 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
index 9105f02f..ca88b6c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.png
index 136d6126..b3b74f8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/search/search-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/select-style-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/select-style-expected.png
index 6bf3e1b..ee17ccb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/select-style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/select/select-style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/submit/submit-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/submit/submit-appearance-basic-expected.png
index cb0412da..6bd6499 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/submit/submit-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/submit/submit-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/text/input-appearance-bkcolor-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/text/input-appearance-bkcolor-expected.png
index 21ed609..d8b7836f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/text/input-appearance-bkcolor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/text/input-appearance-bkcolor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/text/text-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/text/text-appearance-basic-expected.png
index 48beaa39..ac8d6e6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/text/text-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/text/text-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/textarea/textarea-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/textarea/textarea-appearance-basic-expected.png
index fbfb854..76849d0b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/textarea/textarea-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/forms/textarea/textarea-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index e868e424..ad0e230 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-cell-expected.png
index 748a45a89..7fba16e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-collapsed-border-expected.png
index 8bd8a0c5..68059da6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index 111977d..620bdfc6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-expected.png
index 0f42d150..ddf6c64d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index c1dfbc3..7cff2ff 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-group-expected.png
index 8e1bd82..412f67f2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-expected.png
index a28d673..a6ee4c5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index 5dbfbd4..b1facaa 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-expected.png
index afd42dd1..7f2a6d7c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index 820cd47..27c20720 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-group-expected.png
index 37df9296..6ab30b2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index 8a320b3f..b6fe849 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index e868e424..ad0e230 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
new file mode 100644
index 0000000..7fba16e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
index 8bd8a0c5..68059da6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index 111977d..620bdfc6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
new file mode 100644
index 0000000..ddf6c64d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index c1dfbc3..7cff2ff 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
new file mode 100644
index 0000000..412f67f2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
new file mode 100644
index 0000000..a6ee4c5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index 5dbfbd4..b1facaa 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
new file mode 100644
index 0000000..7f2a6d7c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index 820cd47..27c20720 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
new file mode 100644
index 0000000..6ab30b2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
index d5ae38c..97498ed 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac-retina/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/direct-image-compositing-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/direct-image-compositing-expected.png
index 5f3772f..208bc07d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/compositing/direct-image-compositing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/direct-image-compositing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/geometry/horizontal-scroll-composited-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/geometry/horizontal-scroll-composited-expected.png
deleted file mode 100644
index 45d581c..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/compositing/geometry/horizontal-scroll-composited-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/compositing/geometry/vertical-scroll-composited-expected.png b/third_party/WebKit/LayoutTests/platform/mac/compositing/geometry/vertical-scroll-composited-expected.png
index 2f459985..82dd348 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/compositing/geometry/vertical-scroll-composited-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/compositing/geometry/vertical-scroll-composited-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/basic/comments-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/basic/comments-expected.png
index 405ae64..611eb000 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/basic/comments-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/basic/comments-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/basic/containment-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/basic/containment-expected.png
index 5b514fa..695152d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/basic/containment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/basic/containment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/basic/contextual_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/basic/contextual_selectors-expected.png
index 296b86f1..f6433d4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/basic/contextual_selectors-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/basic/contextual_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/basic/grouping-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/basic/grouping-expected.png
index 815ca1b..aadc2bb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/basic/grouping-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/basic/grouping-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/basic/id_as_selector-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/basic/id_as_selector-expected.png
index fb05b5d..543506e5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/basic/id_as_selector-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/basic/id_as_selector-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/basic/inheritance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/basic/inheritance-expected.png
index 3bf7731..7159661 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/basic/inheritance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/basic/inheritance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border-expected.png
index 5d3c32d..75cb129 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom-expected.png
index 84f9191..67e2c8a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom_inline-expected.png
index dd0b7c03..e40018a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom_width-expected.png
index 0458d0d..1bcf2b9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom_width_inline-expected.png
index 45748e41..35e0e2e6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_bottom_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_color-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_color-expected.png
index ea70e5e..ad2b1ce 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_color-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_color_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_color_inline-expected.png
index 84ea7cd1..6bc69a0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_color_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_color_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_inline-expected.png
index 9c30b54..10f28e5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left-expected.png
index 1d3f6462..b9bb4f6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left_inline-expected.png
index 7e06c536..63e7d50 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left_width-expected.png
index d1faf50..c6c09e1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left_width_inline-expected.png
index 3dfcb8c6..9ddb4ee8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_left_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right-expected.png
index a6fedfcc..dc4441b4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right_inline-expected.png
index bf1ce3ed..e9267fe 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right_width-expected.png
index 3560deb..48d2556 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right_width_inline-expected.png
index 74e3c31..69f8831 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_right_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_style-expected.png
index 85a2a03..1e1746a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_style_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_style_inline-expected.png
index a01b903..f12f04bf 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_style_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_style_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top-expected.png
index 71a6cb9..b28cdf5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top_inline-expected.png
index f5a56fc..de584c6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top_width-expected.png
index 73d7c6e..fe78b87 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top_width_inline-expected.png
index 90ecb520..827e23b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_top_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_width-expected.png
index e6f1f18..032c13b8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_width_inline-expected.png
index 563a0f8..38b099c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/border_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/clear-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/clear-expected.png
index ad95799..374040b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/clear-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/clear-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/clear_float-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/clear_float-expected.png
index c457405b..49383bf 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/clear_float-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/clear_float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float-expected.png
index 25038d5..54d72423 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float_elements_in_series-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float_elements_in_series-expected.png
index ad49916e..f2c4653 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float_elements_in_series-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float_elements_in_series-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float_margin-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float_margin-expected.png
index d4855ce..ee8aed1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float_margin-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float_margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float_on_text_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float_on_text_elements-expected.png
index a2bbe7d6..d93b3037 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float_on_text_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/float_on_text_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/height-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/height-expected.png
index 45612ba9..bc437b1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin-expected.png
index a1e3b24..81377c8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_bottom-expected.png
index b1d0159..a0ad3cc7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_bottom_inline-expected.png
index 48e080c4a..935a55b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_bottom_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_inline-expected.png
index 0c162df..9392e10 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_left-expected.png
index d957d69..98e23a4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_left_inline-expected.png
index 4f4107d..5234092 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_left_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_right-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_right-expected.png
index c4ca872..ae9c38f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_right_inline-expected.png
index f46ee83..8cada02d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_top-expected.png
index 75d9e7f..f1fa4fe 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_top_inline-expected.png
index 43932a1..14f669d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_top_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/margin_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding-expected.png
index d2fd48ce..e0ddfa3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_bottom-expected.png
index ee2a1e2d..6354289 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_bottom_inline-expected.png
index 9c99f51..a7a00a3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_bottom_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_inline-expected.png
index e1b7e227..f5158ed6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_left-expected.png
index 5f8603c..c5a47e3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_left_inline-expected.png
index 0ab7804..d5c16a5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_left_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_right-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_right-expected.png
index d3dd1ba..97829204 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_right_inline-expected.png
index fe2d1ce..3bd4424 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_top-expected.png
index 060c3e8a..2020db5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_top_inline-expected.png
index aab74a1..2ddb9bd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_top_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/padding_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/width-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/width-expected.png
index 2981ad5..6aca593 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/box_properties/width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/cascade/cascade_order-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/cascade/cascade_order-expected.png
index da728f24..83890f5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/cascade/cascade_order-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/cascade/cascade_order-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/cascade/important-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/cascade/important-expected.png
index b11aa90..d4324c86 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/cascade/important-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/cascade/important-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/classification/display-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/classification/display-expected.png
index aa17561..a263edd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/classification/display-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/classification/display-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style-expected.png
index 49fc1be..dbd39fa 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style_image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style_image-expected.png
index eeccd98..cedd682 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style_image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style_position-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style_position-expected.png
index 8ec70df..af53567 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style_position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style_position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style_type-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style_type-expected.png
index 2c26b31..85e4700 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style_type-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/classification/list_style_type-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/classification/white_space-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/classification/white_space-expected.png
index 9c6003a6..aae2dcc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/classification/white_space-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/classification/white_space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/background_color-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/background_color-expected.png
index f4488f7..4a04488 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/background_color-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/background_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/background_image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/background_image-expected.png
index 93cf295d..74474379 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/background_image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/background_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/background_repeat-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/background_repeat-expected.png
index f2a96c8..587690b6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/background_repeat-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/background_repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/color-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/color-expected.png
index 7a3efb8..36f01bff 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/color-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/color_and_background/color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/conformance/forward_compatible_parsing-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/conformance/forward_compatible_parsing-expected.png
index 1439750..3696531 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/conformance/forward_compatible_parsing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/conformance/forward_compatible_parsing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font-expected.png
index 73638e99..3d0f00d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_family-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_family-expected.png
index 63c5071..991937b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_family-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_family-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_size-expected.png
index b65e3ba..44bd4693 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_style-expected.png
index eb2d611..5fed2587 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_variant-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_variant-expected.png
index 3789b3d..59cff5c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_variant-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_variant-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_weight-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_weight-expected.png
index eef1fe91..626d3e8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_weight-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/font_properties/font_weight-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/floating_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/floating_elements-expected.png
index a3b97f7c..551badd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/floating_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/floating_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/height_of_lines-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/height_of_lines-expected.png
index c3de95d..4661207 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/height_of_lines-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/height_of_lines-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/horizontal_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/horizontal_formatting-expected.png
index d188969..75c93536 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/horizontal_formatting-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/horizontal_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/inline_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/inline_elements-expected.png
index b7534125..f75d506 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/inline_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/inline_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/replaced_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/replaced_elements-expected.png
index f0bfa1e..9087327 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/replaced_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/replaced_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/vertical_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/vertical_formatting-expected.png
index 3847ef8..ddf8ae598 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/vertical_formatting-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/formatting_model/vertical_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/anchor-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/anchor-expected.png
index 057dd50dd..a82ef94 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/anchor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/anchor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/firstletter-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/firstletter-expected.png
index 4933fce..ab4e66e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/firstletter-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/firstletter-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/firstline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/firstline-expected.png
index 34a42c0..2c7d52ab 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/firstline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/firstline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/multiple_pseudo_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/multiple_pseudo_elements-expected.png
index 0d43711e..138a89b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/multiple_pseudo_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/multiple_pseudo_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/pseudo_elements_in_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/pseudo_elements_in_selectors-expected.png
index fa804307..de01dae 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/pseudo_elements_in_selectors-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/pseudo/pseudo_elements_in_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/letter_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/letter_spacing-expected.png
index a1516f3..6620140f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/letter_spacing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/letter_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/line_height-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/line_height-expected.png
index fefc70f1..c7eff30c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/line_height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/line_height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_align-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_align-expected.png
index 55da9bf..dfde0225 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_align-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_decoration-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_decoration-expected.png
index a444260..ff91bc4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_decoration-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_decoration-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_indent-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_indent-expected.png
index 1eb345f..8ced972 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_indent-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_indent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_transform-expected.png
index db70e4be..41712278 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/text_transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/vertical_align-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/vertical_align-expected.png
index 220af9b..2c165389 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/vertical_align-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/vertical_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/word_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/word_spacing-expected.png
index f6f62f63..ed9a261b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/word_spacing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/text_properties/word_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/units/color_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/units/color_units-expected.png
index a786e8f..f770597 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/units/color_units-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/units/color_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/units/length_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/units/length_units-expected.png
index 2662f69b..10d53b5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/units/length_units-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/units/length_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css1/units/percentage_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css1/units/percentage_units-expected.png
index 26afa66..22003709 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css1/units/percentage_units-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css1/units/percentage_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-00-a-ag-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-00-a-ag-expected.png
index cbc9b09..5be92507 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-00-a-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-00-a-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-02-d-agi-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-02-d-agi-expected.png
index f0a3d35..9e86ce5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-02-d-agi-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-02-d-agi-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-03-d-agi-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-03-d-agi-expected.png
index e384b6e3..87628c4e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-03-d-agi-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-03-d-agi-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-04-d-agi-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-04-d-agi-expected.png
index b0418b6..c5b9f63 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-04-d-agi-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c544-valgn-04-d-agi-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c548-ln-ht-03-d-ag-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c548-ln-ht-03-d-ag-expected.png
index 6b95dcd..8cfbc84 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c548-ln-ht-03-d-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t100801-c548-ln-ht-03-d-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-00-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-00-c-ag-expected.png
index c8a67086..7433e569 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-00-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-00-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-01-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-01-c-ag-expected.png
index c8a67086..7433e569 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-01-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-01-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-02-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-02-c-ag-expected.png
index c8a67086..d928a72 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-02-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-02-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-03-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-03-c-ag-expected.png
index c8a67086..8c7f6e3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-03-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-03-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-04-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-04-c-ag-expected.png
index c8a67086..96db8cf 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-04-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-04-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-05-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-05-c-ag-expected.png
index c8a67086..87e5aa8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-05-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t140201-c534-bgreps-05-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t1605-c545-txttrans-00-b-ag-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t1605-c545-txttrans-00-b-ag-expected.png
index 27ff02d..945dc06 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css2.1/t1605-c545-txttrans-00-b-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css2.1/t1605-c545-txttrans-00-b-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-tiled-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-tiled-gradient-expected.png
index 3b75e0b..9544359 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-tiled-gradient-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css3/blending/background-blend-mode-tiled-gradient-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/masking/mask-luminance-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/masking/mask-luminance-gradient-expected.png
new file mode 100644
index 0000000..82ea862
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/css3/masking/mask-luminance-gradient-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/css3/masking/mask-repeat-space-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/css3/masking/mask-repeat-space-border-expected.png
index f5dca37..7a359d1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/css3/masking/mask-repeat-space-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/css3/masking/mask-repeat-space-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-repeat-with-background-color-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-repeat-with-background-color-expected.png
new file mode 100644
index 0000000..72270a2
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-repeat-with-background-color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-svg-scaling-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-svg-scaling-expected.png
new file mode 100644
index 0000000..310153a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-svg-scaling-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-svg-scaling-zoom-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-svg-scaling-zoom-expected.png
index b00a069a..7957284 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-svg-scaling-zoom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/background-svg-scaling-zoom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/border-radius-split-background-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/border-radius-split-background-image-expected.png
index 0e206f7..aef04a2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/border-radius-split-background-image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/border-radius-split-background-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-expected.png
index cdefb82..49c8d25f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png
index b8849642..ec603dd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/size/backgroundSize15-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/size/backgroundSize15-expected.png
new file mode 100644
index 0000000..6ae807a17
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/backgrounds/size/backgroundSize15-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-01-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-01-expected.png
index 28442280..afc3214a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-01-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-01-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-border-radius-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-border-radius-expected.png
index 92a5ffa..7113991 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-border-radius-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-border-radius-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-longhand-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-longhand-expected.png
index 28442280..afc3214a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-longhand-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-longhand-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-expected.png
index 1b66a607..793deb4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-in-shorthand-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-in-shorthand-expected.png
index 1b66a607..793deb4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-in-shorthand-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-in-shorthand-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-split-inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-split-inline-expected.png
index 745d283..4a3b1d9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-split-inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-outset-split-inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-expected.png
index 28442280..afc3214a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-round-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-round-expected.png
index 8102267..f08a2381 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-round-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-repeat-round-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scrambled-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scrambled-expected.png
index 28442280..afc3214a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scrambled-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-scrambled-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-slices-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-slices-expected.png
index 849500b..a9f10eb 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-slices-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-slices-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-source-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-source-expected.png
index 28442280..afc3214a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-source-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/border-image-source-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/scaled-border-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/scaled-border-image-expected.png
index 7bc1bf66..f0c37b1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/borders/scaled-border-image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/borders/scaled-border-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/image-object-in-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/image-object-in-canvas-expected.png
index 2d8c579..ebff45f8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/image-object-in-canvas-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/image-object-in-canvas-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/patternfill-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/patternfill-repeat-expected.png
new file mode 100644
index 0000000..f131eb8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/patternfill-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/patternfill-repeat-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/patternfill-repeat-expected.txt
new file mode 100644
index 0000000..5b140e7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/canvas/patternfill-repeat-expected.txt
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x460
+  LayoutBlockFlow {HTML} at (0,0) size 800x460
+    LayoutBlockFlow {BODY} at (8,16) size 784x428
+      LayoutBlockFlow {P} at (0,0) size 784x72
+        LayoutText {#text} at (0,0) size 785x72
+          text run at (0,0) width 761: "There should be one big square below containing four squares. Top left square should be filled with 3 rows of 2 and bit"
+          text run at (0,18) width 785: "Apple images. Top right square should be 2 and a bit rows with one Apple image column along the left edge of the square."
+          text run at (0,36) width 778: "Bottom left square should be one row with three Apple images along the top of the square. Bottom right square should be"
+          text run at (0,54) width 224: "one Apple image in top left corner."
+      LayoutBlockFlow {P} at (0,88) size 784x340
+layer at (8,104) size 336x336
+  LayoutHTMLCanvas {CANVAS} at (0,0) size 336x336 [border: (3px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/background-image-with-baseurl-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/background-image-with-baseurl-expected.png
index 28a08e1..001a7bef 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/background-image-with-baseurl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/background-image-with-baseurl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/import_with_baseurl-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/import_with_baseurl-expected.png
index 28a08e1..001a7bef 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/css/import_with_baseurl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/import_with_baseurl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/text-overflow-ellipsis-multiple-shadows-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/css/text-overflow-ellipsis-multiple-shadows-expected.png
new file mode 100644
index 0000000..fbf738be3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/text-overflow-ellipsis-multiple-shadows-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/css/text-overflow-ellipsis-multiple-shadows-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/css/text-overflow-ellipsis-multiple-shadows-expected.txt
new file mode 100644
index 0000000..d1cd344
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/css/text-overflow-ellipsis-multiple-shadows-expected.txt
@@ -0,0 +1,9 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x8
+  LayoutBlockFlow {HTML} at (0,0) size 800x8
+    LayoutBlockFlow {BODY} at (8,8) size 784x0
+layer at (0,0) size 144x83 scrollWidth 160
+  LayoutBlockFlow (positioned) {DIV} at (0,0) size 144x83
+    LayoutText {#text} at (0,0) size 161x83
+      text run at (0,0) width 161: "Blink"
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
index a94e135e..a6d53aa 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
index d32f491d..6b2b520 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
index b14ed6f..1fb73e4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
index defbd208..4638e08 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
index 28cba5a..9a22c6e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
index f867a6c..1794673 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
index d2215b4..764989b3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
index 663208e..c100f51 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
index cb90ec47..4d8be3a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
index 6568af3..9d038b9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-expected.png
index eb6100d..c6244d6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
index ab8df069..d5354e1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-expected.png
index 31500b88..078269f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
index e4e1574..8c07c2d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.png
index fda9258..ee82ae7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/search/search-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-style-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-style-expected.png
index b05b4725..994b1dc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/select/select-style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/submit/submit-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/submit/submit-appearance-basic-expected.png
index 6690b541..b6c38a7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/submit/submit-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/submit/submit-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/input-appearance-bkcolor-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/input-appearance-bkcolor-expected.png
index ea50b40..440507d3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/input-appearance-bkcolor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/input-appearance-bkcolor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/text-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/text-appearance-basic-expected.png
index 0418a53..e66ee962 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/text-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/text/text-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/textarea/textarea-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/textarea/textarea-appearance-basic-expected.png
index 4ef8172..cfe9e9a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/forms/textarea/textarea-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/forms/textarea/textarea-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/conic-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/conic-gradient-expected.png
index c3fecf5..36452cf 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/conic-gradient-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/conic-gradient-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/conic-gradient-out-of-range-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/conic-gradient-out-of-range-expected.png
index f59fe9f..d62258a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/conic-gradient-out-of-range-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/conic-gradient-out-of-range-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/conic-gradient-positioning-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/conic-gradient-positioning-expected.png
index 0bfd6999..313664b3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/conic-gradient-positioning-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/conic-gradient-positioning-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/crash-on-zero-radius-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/crash-on-zero-radius-expected.png
index 5e88016a..72712cd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/crash-on-zero-radius-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/crash-on-zero-radius-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/repeating-conic-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/repeating-conic-gradient-expected.png
index fa581521..19c5790 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/repeating-conic-gradient-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/repeating-conic-gradient-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/simple-gradients-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/simple-gradients-expected.png
index 3563ef2..db801647 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/simple-gradients-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/simple-gradients-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/unprefixed-linear-gradients-color-hints-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/unprefixed-linear-gradients-color-hints-expected.png
new file mode 100644
index 0000000..06ee798
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/unprefixed-linear-gradients-color-hints-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/unprefixed-radial-gradients-color-hints-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/unprefixed-radial-gradients-color-hints-expected.png
index 229d4aac..c80284f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/unprefixed-radial-gradients-color-hints-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/unprefixed-radial-gradients-color-hints-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/unprefixed-repeating-gradient-color-hint-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/unprefixed-repeating-gradient-color-hint-expected.png
index 7a71668..754913b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/unprefixed-repeating-gradient-color-hint-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/gradients/unprefixed-repeating-gradient-color-hint-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-with-local-background-attachment-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-with-local-background-attachment-expected.png
index 672bfa6..498a834 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-with-local-background-attachment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/overflow-with-local-background-attachment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index 5e5784f..e5b07af 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-expected.png
index 23efd1c8..8a1ac6c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.png
index eb4cc78..7be463d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index c25dc53..994dde02 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-expected.png
index 022f858..ce4acbd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index 02e1e37..0c707a7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-expected.png
index c38ab52c..ee9d287 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-expected.png
index e6365bd..f2bc88dc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index 1b872d65..6869a5ddf 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-expected.png
index 7981272..d93d238 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index c929fee..60575fe8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-expected.png
index c7097d2..2563d18 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/tbody-background-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/tbody-background-image-expected.png
index ab1318c..709b6da1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/table/tbody-background-image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/tbody-background-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/table/tbody-background-image-repeat-x-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/table/tbody-background-image-repeat-x-expected.png
new file mode 100644
index 0000000..5b0fc5c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/table/tbody-background-image-repeat-x-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-lr-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-lr-expected.png
index ebf2297..a384974 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-lr-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-lr-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-rl-expected.png b/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-rl-expected.png
index a87e9a7a..e9848bbf 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-rl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/writing-mode/border-image-vertical-rl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/mac/http/tests/misc/slow-loading-image-in-pattern-expected.png
index 8cb08652..357add5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/http/tests/misc/slow-loading-image-in-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/http/tests/misc/slow-loading-image-in-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png
index 2b95f88..00cc682a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-repeat-space-padding-box-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-repeat-space-padding-box-expected.png
index 81becfc..81fe623 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-repeat-space-padding-box-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background-repeat-space-padding-box-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_repeat_space_border_box-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_repeat_space_border_box-expected.png
index e3e4738..8932bbf 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_repeat_space_border_box-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_repeat_space_border_box-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png
index a672bc9..269e2cd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-clip-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-clip-text-expected.png
index 12bc6570..0854a6f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-clip-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-clip-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-image-space-expected.png
index c5d0b0f0..c1ba2de 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-image-space-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-background-image-space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-border-image-source-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-border-image-source-expected.png
index 28442280..afc3214a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-border-image-source-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-border-image-source-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-group-expected.png
index 04354ed..c19b307 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-svg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-svg-expected.png
index 13240f5..2dabcc9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-svg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/images/color-profile-svg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/images/cross-fade-background-size-expected.png
index 1bd3c48..1820652 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/images/cross-fade-background-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/images/cross-fade-background-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png
index c16b0de5..93579731 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/overflow/fixed-background-scroll-window-expected.png b/third_party/WebKit/LayoutTests/platform/mac/paint/overflow/fixed-background-scroll-window-expected.png
new file mode 100644
index 0000000..2897310
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/overflow/fixed-background-scroll-window-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/paint/overflow/fixed-background-scroll-window-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/paint/overflow/fixed-background-scroll-window-expected.txt
new file mode 100644
index 0000000..1f09880
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/paint/overflow/fixed-background-scroll-window-expected.txt
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600 scrollY 1000.00 scrollHeight 4016
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x4016 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x4016
+    LayoutBlockFlow {BODY} at (8,8) size 784x4000
+layer at (8,1116) size 666x18 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutBlockFlow (positioned) {P} at (8,1116) size 665.63x18
+    LayoutText {#text} at (0,0) size 666x18
+      text run at (0,0) width 666: "Tests painting of fixed background content in scrolled container. Passes if the background doesn't scroll."
+scrolled to 0,1000
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png
index b95330f3f..e5a97812 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/pservers-pattern-04-f-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/pservers-pattern-04-f-expected.png
index ea5d5889..5be4f8f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/pservers-pattern-04-f-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1-SE/pservers-pattern-04-f-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-36-t-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-36-t-expected.png
index 2368096..772e114 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-36-t-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/animate-elem-36-t-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/coords-units-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/coords-units-01-b-expected.png
index 2cc86e3..2f34f8b8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/coords-units-01-b-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/W3C-SVG-1.1/coords-units-01-b-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-expected.png
index b2d94fe..22e2ae21 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-positioned-objects-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-positioned-objects-expected.png
index a3df7915..76b0050c 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-positioned-objects-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/paints/patternRegions-positioned-objects-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textDecoration-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textDecoration-expected.png
index c8039bce..0fe7a41b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textDecoration-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/batik/text/textDecoration-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/canvas/canvas-default-object-sizing-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/canvas/canvas-default-object-sizing-expected.png
new file mode 100644
index 0000000..c6c557f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/canvas/canvas-default-object-sizing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/canvas/canvas-pattern-svg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/canvas/canvas-pattern-svg-expected.png
index e592392..cfa94a21 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/canvas/canvas-pattern-svg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/canvas/canvas-pattern-svg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/convolution-crash-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/convolution-crash-expected.png
index 6499bd2..7367bcc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/convolution-crash-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/convolution-crash-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/masking-clipping-hidpi-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/masking-clipping-hidpi-expected.png
index 2724ab5..1defd79 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/masking-clipping-hidpi-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/masking-clipping-hidpi-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/pattern-cycle-detection-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/pattern-cycle-detection-expected.png
index 7b945ce..cfdbb626 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/pattern-cycle-detection-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/pattern-cycle-detection-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/pattern-deep-referencing-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/pattern-deep-referencing-expected.png
index bba1350..ed859365 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/pattern-deep-referencing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/pattern-deep-referencing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/pattern-incorrect-tiling-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/pattern-incorrect-tiling-expected.png
index a29f3e7..87eca1dd4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/pattern-incorrect-tiling-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/pattern-incorrect-tiling-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/stroked-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/stroked-pattern-expected.png
index 3aaf20db..1977e20 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/stroked-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/stroked-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/transformed-text-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/transformed-text-pattern-expected.png
new file mode 100644
index 0000000..aace6c7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/transformed-text-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/transformed-text-pattern-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/transformed-text-pattern-expected.txt
new file mode 100644
index 0000000..43d31df
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/transformed-text-pattern-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x238
+  LayoutBlockFlow {HTML} at (0,0) size 800x238
+    LayoutBlockFlow {BODY} at (8,8) size 784x222
+      LayoutText {#text} at (0,0) size 327x18
+        text run at (0,0) width 327: "This test passes if there is an A and a green square."
+      LayoutBR {BR} at (326,0) size 1x18
+      LayoutSVGRoot {svg} at (0,18) size 200x200
+        LayoutSVGHiddenContainer {defs} at (0,0) size 0x0
+          LayoutSVGResourcePattern {pattern} [id="pattern"] [patternUnits=userSpaceOnUse] [patternContentUnits=userSpaceOnUse] [patternTransform={m=((10.00,0.00)(0.00,10.00)) t=(0.00,0.00)}]
+            LayoutSVGContainer {g} at (0,40) size 100x70 [transform={m=((0.10,0.00)(0.00,0.10)) t=(0.00,0.00)}]
+              LayoutSVGRect {rect} at (55,55) size 45x45 [fill={[type=SOLID] [color=#008000]}] [x=55.00] [y=55.00] [width=45.00] [height=45.00]
+              LayoutSVGText {text} at (0,40) size 41.02x70 contains 1 chunk(s)
+                LayoutSVGInlineText {#text} at (0,40) size 41.02x70
+                  chunk 1 text run 1 at (0.00,100.00) startOffset 0 endOffset 1 width 41.02: "A"
+        LayoutSVGRect {rect} at (0,0) size 400x200 [fill={[type=PATTERN] [id="pattern"]}] [x=0.00] [y=0.00] [width=400.00] [height=200.00]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/use-on-symbol-inside-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/use-on-symbol-inside-pattern-expected.png
index a19fb2a..f0424460 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/custom/use-on-symbol-inside-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/custom/use-on-symbol-inside-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/filters/feImage-preserveAspectRatio-all-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/filters/feImage-preserveAspectRatio-all-expected.png
index e67db00f..4a3d90e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/filters/feImage-preserveAspectRatio-all-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/filters/feImage-preserveAspectRatio-all-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-decorations-in-scaled-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-decorations-in-scaled-pattern-expected.png
index 3731470..873aa80 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-decorations-in-scaled-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/text/text-decorations-in-scaled-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/transformed-text-fill-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/transformed-text-fill-pattern-expected.png
new file mode 100644
index 0000000..5b67194
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/svg/transforms/transformed-text-fill-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1067-1-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1067-1-expected.png
index 89498e4..493c0be9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1067-1-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1067-1-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug12008-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug12008-expected.png
index aeba0f5..a4f35e12 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug12008-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug12008-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1271-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1271-expected.png
deleted file mode 100644
index 8b73b9b1..0000000
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1271-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1296-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1296-expected.png
index f20649c..e097a9a6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1296-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1296-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1430-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1430-expected.png
index 65b85a4..6a17ed9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1430-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla/bugs/bug1430-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index cdb6847..65f644fd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/other/test4-expected.png b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/other/test4-expected.png
index 6980e83b..7bf78a2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/other/test4-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/tables/mozilla_expected_failures/other/test4-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/image-object-in-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/image-object-in-canvas-expected.png
index 3355fa4..ae68f842 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/image-object-in-canvas-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/image-object-in-canvas-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.png
new file mode 100644
index 0000000..f131eb8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.txt
new file mode 100644
index 0000000..5b140e7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.txt
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x460
+  LayoutBlockFlow {HTML} at (0,0) size 800x460
+    LayoutBlockFlow {BODY} at (8,16) size 784x428
+      LayoutBlockFlow {P} at (0,0) size 784x72
+        LayoutText {#text} at (0,0) size 785x72
+          text run at (0,0) width 761: "There should be one big square below containing four squares. Top left square should be filled with 3 rows of 2 and bit"
+          text run at (0,18) width 785: "Apple images. Top right square should be 2 and a bit rows with one Apple image column along the left edge of the square."
+          text run at (0,36) width 778: "Bottom left square should be one row with three Apple images along the top of the square. Bottom right square should be"
+          text run at (0,54) width 224: "one Apple image in top left corner."
+      LayoutBlockFlow {P} at (0,88) size 784x340
+layer at (8,104) size 336x336
+  LayoutHTMLCanvas {CANVAS} at (0,0) size 336x336 [border: (3px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png
index 8ec4a0d..4816f517 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
index 7b65507..5e02c78 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png
index 4f80329..c4262271 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-group-expected.png
index 768286f..66b7e946 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-expected.png
index 9ee60756..150ce0e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/color-profile-svg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-background-size-expected.png
index 7ddaa89..50531bc 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-background-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-background-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png
new file mode 100644
index 0000000..2addd3ee
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/patternfill-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/patternfill-repeat-expected.png
new file mode 100644
index 0000000..e3a6aab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/patternfill-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/patternfill-repeat-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/patternfill-repeat-expected.txt
new file mode 100644
index 0000000..5b140e7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/gpu/fast/canvas/patternfill-repeat-expected.txt
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x460
+  LayoutBlockFlow {HTML} at (0,0) size 800x460
+    LayoutBlockFlow {BODY} at (8,16) size 784x428
+      LayoutBlockFlow {P} at (0,0) size 784x72
+        LayoutText {#text} at (0,0) size 785x72
+          text run at (0,0) width 761: "There should be one big square below containing four squares. Top left square should be filled with 3 rows of 2 and bit"
+          text run at (0,18) width 785: "Apple images. Top right square should be 2 and a bit rows with one Apple image column along the left edge of the square."
+          text run at (0,36) width 778: "Bottom left square should be one row with three Apple images along the top of the square. Bottom right square should be"
+          text run at (0,54) width 224: "one Apple image in top left corner."
+      LayoutBlockFlow {P} at (0,88) size 784x340
+layer at (8,104) size 336x336
+  LayoutHTMLCanvas {CANVAS} at (0,0) size 336x336 [border: (3px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/comments-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/comments-expected.png
index 405ae64..611eb000 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/comments-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/comments-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/containment-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/containment-expected.png
index 5b514fa..695152d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/containment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/containment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/contextual_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/contextual_selectors-expected.png
new file mode 100644
index 0000000..f6433d4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/contextual_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/grouping-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/grouping-expected.png
new file mode 100644
index 0000000..aadc2bb
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/grouping-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/id_as_selector-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/id_as_selector-expected.png
new file mode 100644
index 0000000..543506e5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/id_as_selector-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/inheritance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/inheritance-expected.png
index 3bf7731..7159661 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/inheritance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/basic/inheritance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border-expected.png
index 5d3c32d..75cb129 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png
index 84f9191..67e2c8a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_bottom_inline-expected.png
new file mode 100644
index 0000000..e40018a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png
index 0458d0d..1bcf2b9 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_bottom_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_bottom_width_inline-expected.png
new file mode 100644
index 0000000..35e0e2e6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_bottom_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_color-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_color-expected.png
new file mode 100644
index 0000000..ad2b1ce
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_color_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_color_inline-expected.png
new file mode 100644
index 0000000..6bc69a0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_color_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_inline-expected.png
new file mode 100644
index 0000000..10f28e5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_left-expected.png
index 1d3f6462..b9bb4f6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_left_inline-expected.png
new file mode 100644
index 0000000..63e7d50
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png
index d1faf50..c6c09e1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_left_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_left_width_inline-expected.png
new file mode 100644
index 0000000..9ddb4ee8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_left_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_right-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_right-expected.png
new file mode 100644
index 0000000..dc4441b4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png
index bf1ce3ed..e9267fe 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png
index 3560deb..48d2556 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_right_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_right_width_inline-expected.png
new file mode 100644
index 0000000..69f8831
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_right_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_style-expected.png
index 85a2a03..1e1746a 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png
index a01b903..f12f04bf 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_top-expected.png
index 71a6cb9..b28cdf5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_top_inline-expected.png
new file mode 100644
index 0000000..de584c6
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png
index 73d7c6e..fe78b87 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_top_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_top_width_inline-expected.png
new file mode 100644
index 0000000..827e23b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_top_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_width-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_width-expected.png
index e6f1f18..032c13b8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_width_inline-expected.png
new file mode 100644
index 0000000..38b099c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/border_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/clear-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/clear-expected.png
index ad95799..374040b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/clear-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/clear-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/clear_float-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/clear_float-expected.png
index c457405b..49383bf 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/clear_float-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/clear_float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/float-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/float-expected.png
new file mode 100644
index 0000000..54d72423
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png
index ad49916e..f2c4653 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/float_margin-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/float_margin-expected.png
new file mode 100644
index 0000000..ee8aed1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/float_margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/float_on_text_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/float_on_text_elements-expected.png
new file mode 100644
index 0000000..d93b3037
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/float_on_text_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/height-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/height-expected.png
index 45612ba9..bc437b1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin-expected.png
new file mode 100644
index 0000000..81377c8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_bottom-expected.png
new file mode 100644
index 0000000..a0ad3cc7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_bottom_inline-expected.png
new file mode 100644
index 0000000..935a55b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png
index 0c162df..9392e10 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_left-expected.png
index d957d69..98e23a4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_left_inline-expected.png
new file mode 100644
index 0000000..5234092
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_right-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_right-expected.png
index c4ca872..ae9c38f 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_right_inline-expected.png
new file mode 100644
index 0000000..8cada02d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_top-expected.png
new file mode 100644
index 0000000..f1fa4fe
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_top_inline-expected.png
new file mode 100644
index 0000000..14f669d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/margin_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding-expected.png
new file mode 100644
index 0000000..e0ddfa3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_bottom-expected.png
new file mode 100644
index 0000000..6354289
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_bottom_inline-expected.png
new file mode 100644
index 0000000..a7a00a3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png
index e1b7e227..f5158ed6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_left-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_left-expected.png
index 5f8603c..c5a47e3 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_left_inline-expected.png
new file mode 100644
index 0000000..d5c16a5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_right-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_right-expected.png
new file mode 100644
index 0000000..97829204
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_right_inline-expected.png
new file mode 100644
index 0000000..3bd4424
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_top-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_top-expected.png
new file mode 100644
index 0000000..2020db5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_top_inline-expected.png
new file mode 100644
index 0000000..2ddb9bd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/padding_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/width-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/width-expected.png
new file mode 100644
index 0000000..6aca593
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/box_properties/width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/cascade/cascade_order-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/cascade/cascade_order-expected.png
index da728f24..83890f5 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/cascade/cascade_order-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/cascade/cascade_order-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/cascade/important-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/cascade/important-expected.png
new file mode 100644
index 0000000..d4324c86
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/cascade/important-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/display-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/display-expected.png
index aa17561..a263edd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/display-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/display-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/list_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/list_style-expected.png
new file mode 100644
index 0000000..dbd39fa
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/list_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/list_style_image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/list_style_image-expected.png
new file mode 100644
index 0000000..cedd682
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/list_style_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/list_style_position-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/list_style_position-expected.png
index 8ec70df..af53567 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/list_style_position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/list_style_position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/list_style_type-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/list_style_type-expected.png
new file mode 100644
index 0000000..85e4700
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/list_style_type-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/white_space-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/white_space-expected.png
new file mode 100644
index 0000000..aae2dcc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/classification/white_space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/color_and_background/background_color-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/color_and_background/background_color-expected.png
new file mode 100644
index 0000000..4a04488
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/color_and_background/background_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/color_and_background/background_image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/color_and_background/background_image-expected.png
new file mode 100644
index 0000000..74474379
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/color_and_background/background_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png
index f2a96c8..587690b6 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/color_and_background/color-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/color_and_background/color-expected.png
new file mode 100644
index 0000000..36f01bff
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/color_and_background/color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/conformance/forward_compatible_parsing-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/conformance/forward_compatible_parsing-expected.png
new file mode 100644
index 0000000..3696531
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/conformance/forward_compatible_parsing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font-expected.png
new file mode 100644
index 0000000..3d0f00d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font_family-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font_family-expected.png
new file mode 100644
index 0000000..991937b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font_family-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font_size-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font_size-expected.png
new file mode 100644
index 0000000..44bd4693
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font_size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font_style-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font_style-expected.png
new file mode 100644
index 0000000..5fed2587
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font_variant-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font_variant-expected.png
new file mode 100644
index 0000000..59cff5c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font_variant-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font_weight-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font_weight-expected.png
new file mode 100644
index 0000000..626d3e8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/font_properties/font_weight-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/floating_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/floating_elements-expected.png
new file mode 100644
index 0000000..551badd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/floating_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/height_of_lines-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/height_of_lines-expected.png
new file mode 100644
index 0000000..4661207
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/height_of_lines-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/horizontal_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/horizontal_formatting-expected.png
new file mode 100644
index 0000000..75c93536
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/horizontal_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png
index b7534125..f75d506 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/replaced_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/replaced_elements-expected.png
new file mode 100644
index 0000000..9087327
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/replaced_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/vertical_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/vertical_formatting-expected.png
new file mode 100644
index 0000000..ddf8ae598
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/formatting_model/vertical_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/anchor-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/anchor-expected.png
index 057dd50dd..a82ef94 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/anchor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/anchor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/firstletter-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/firstletter-expected.png
index 4933fce..ab4e66e 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/firstletter-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/firstletter-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/firstline-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/firstline-expected.png
index 34a42c0..2c7d52ab 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/firstline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/firstline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
index 0d43711e..138a89b 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/pseudo_elements_in_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/pseudo_elements_in_selectors-expected.png
new file mode 100644
index 0000000..de01dae
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/pseudo/pseudo_elements_in_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/letter_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/letter_spacing-expected.png
new file mode 100644
index 0000000..6620140f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/letter_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/line_height-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/line_height-expected.png
new file mode 100644
index 0000000..c7eff30c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/line_height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/text_align-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/text_align-expected.png
new file mode 100644
index 0000000..dfde0225
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/text_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png
index a444260..ff91bc4 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/text_indent-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/text_indent-expected.png
new file mode 100644
index 0000000..8ced972
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/text_indent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/text_transform-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/text_transform-expected.png
index db70e4be..41712278 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/text_transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/text_transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/vertical_align-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/vertical_align-expected.png
new file mode 100644
index 0000000..2c165389
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/vertical_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/word_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/word_spacing-expected.png
new file mode 100644
index 0000000..ed9a261b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/text_properties/word_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/units/color_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/units/color_units-expected.png
new file mode 100644
index 0000000..f770597
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/units/color_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/units/length_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/units/length_units-expected.png
new file mode 100644
index 0000000..10d53b5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/units/length_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/units/percentage_units-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/units/percentage_units-expected.png
new file mode 100644
index 0000000..22003709
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/css1/units/percentage_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index 5e5784f..e5b07af 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
new file mode 100644
index 0000000..8a1ac6c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
index eb4cc78..7be463d 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index c25dc53..994dde02 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
new file mode 100644
index 0000000..ce4acbd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index 02e1e37..0c707a7 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
new file mode 100644
index 0000000..ee9d287
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
new file mode 100644
index 0000000..f2bc88dc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index 1b872d65..6869a5ddf 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
new file mode 100644
index 0000000..d93d238
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index c929fee..60575fe8 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
new file mode 100644
index 0000000..2563d18
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/tbody-background-image-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/tbody-background-image-expected.png
index ab1318c..709b6da1 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/tbody-background-image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/tbody-background-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/tbody-background-image-repeat-x-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/tbody-background-image-repeat-x-expected.png
new file mode 100644
index 0000000..5b0fc5c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/fast/table/tbody-background-image-repeat-x-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png
new file mode 100644
index 0000000..357add5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/off-main-thread-fetch/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/off-main-thread-fetch/http/tests/misc/slow-loading-image-in-pattern-expected.png
new file mode 100644
index 0000000..357add5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/off-main-thread-fetch/http/tests/misc/slow-loading-image-in-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/mac/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/mac/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
index dc4c481..e55ba6e0 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/mac/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/direct-image-compositing-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/direct-image-compositing-expected.png
index 629be2fc2..bf862658 100644
--- a/third_party/WebKit/LayoutTests/platform/win/compositing/direct-image-compositing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/compositing/direct-image-compositing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/geometry/horizontal-scroll-composited-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/geometry/horizontal-scroll-composited-expected.png
deleted file mode 100644
index d4f3d2a..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/compositing/geometry/horizontal-scroll-composited-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/compositing/geometry/vertical-scroll-composited-expected.png b/third_party/WebKit/LayoutTests/platform/win/compositing/geometry/vertical-scroll-composited-expected.png
index f08c2b5..481fc39 100644
--- a/third_party/WebKit/LayoutTests/platform/win/compositing/geometry/vertical-scroll-composited-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/compositing/geometry/vertical-scroll-composited-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/basic/comments-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/basic/comments-expected.png
index aaaaf63..41626ca 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/basic/comments-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/basic/comments-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/basic/containment-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/basic/containment-expected.png
index d605a30..63fb91d0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/basic/containment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/basic/containment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/basic/contextual_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/basic/contextual_selectors-expected.png
index 493438e..4298466 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/basic/contextual_selectors-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/basic/contextual_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/basic/grouping-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/basic/grouping-expected.png
index fc148325..1fefd99f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/basic/grouping-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/basic/grouping-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/basic/id_as_selector-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/basic/id_as_selector-expected.png
index 9596269..78fa596 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/basic/id_as_selector-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/basic/id_as_selector-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/basic/inheritance-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/basic/inheritance-expected.png
index 05a0dc1..e00fdff 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/basic/inheritance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/basic/inheritance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border-expected.png
index ded3379..6a35cc4 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom-expected.png
index 9eb228c..040c6ff 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom_inline-expected.png
index 89d03be..65f0a18 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom_width-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom_width-expected.png
index cdeb031f..12e20a8 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom_width_inline-expected.png
index 86f0fae3..3ab4f38 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_bottom_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_color-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_color-expected.png
index 5eff7ff..88b119f7f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_color-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_color_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_color_inline-expected.png
index fbaeed1..1d064a0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_color_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_color_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_inline-expected.png
index 074aca728..ef0578b 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left-expected.png
index 7046381..dcbd26ae 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left_inline-expected.png
index 027a1e36..e521877 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left_width-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left_width-expected.png
index 934737d..dd54e8f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left_width_inline-expected.png
index 9918a9d..bfba7fb4 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_left_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right-expected.png
index 9c3c318..ce3d48d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right_inline-expected.png
index 5c418a3..1b7396c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right_width-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right_width-expected.png
index 6ace20de..97681ab 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right_width_inline-expected.png
index eab4e60..b3003b0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_right_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_style-expected.png
index 52c9a5b1..ae1ea65 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_style_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_style_inline-expected.png
index 30adad6c..b924c6c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_style_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_style_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top-expected.png
index 7fae42b..ad05519 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top_inline-expected.png
index 05a572d..de39c94 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top_width-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top_width-expected.png
index 2bc0c02..ab0db171a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top_width_inline-expected.png
index fc1f69a..80f7dc52 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_top_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_width-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_width-expected.png
index 852dcf53..aa12e98 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_width_inline-expected.png
index 6b718b1..49f7b2b 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_width_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/border_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/clear-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/clear-expected.png
index 7c3d99fb..df5579bf 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/clear-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/clear-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/clear_float-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/clear_float-expected.png
index 4dcf105..6f4c26c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/clear_float-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/clear_float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float-expected.png
index 706ff9c8..f1d5b94 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float_elements_in_series-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float_elements_in_series-expected.png
index f5ffaf3c..72420e70 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float_elements_in_series-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float_elements_in_series-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float_margin-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float_margin-expected.png
index a76c748..1ecfc9b4 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float_margin-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float_margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float_on_text_elements-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float_on_text_elements-expected.png
index a0ee1de..7c9c9a0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float_on_text_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/float_on_text_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/height-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/height-expected.png
index 1f789a9..3926c91 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin-expected.png
index 23945df..81a89f5 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_bottom-expected.png
index 79cf193..7ed09181 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_bottom_inline-expected.png
index 1226065..2cc03f8 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_bottom_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_inline-expected.png
index 5e42be9f..a1c18d4d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_left-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_left-expected.png
index 8243239..e9f4911 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_left_inline-expected.png
index 83c6c3a..b1671bd 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_left_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_right-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_right-expected.png
index 33ca1bcd..551e223d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_right_inline-expected.png
index 963bb0b..a25e1bca 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_top-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_top-expected.png
index aa54f029..c6cef16 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_top_inline-expected.png
index c4d30bf..4a25214 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_top_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/margin_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding-expected.png
index 03e1257..3617bab 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_bottom-expected.png
index 15081963..49f5b12 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_bottom_inline-expected.png
index 9ba2494..af28062 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_bottom_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_inline-expected.png
index 4843da8..2e8ace24 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_left-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_left-expected.png
index d31eecfb..0b10510 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_left_inline-expected.png
index c5f5b137..ef1bb8e7 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_left_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_right-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_right-expected.png
index 4da4ea5..6863efc 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_right_inline-expected.png
index fa1b663..2d390911 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_right_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_top-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_top-expected.png
index 8ed50c94..4939c75 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_top_inline-expected.png
index 063c026..ffc12ba 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_top_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/padding_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/width-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/width-expected.png
index 4fd63c2..717281a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/box_properties/width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/cascade/cascade_order-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/cascade/cascade_order-expected.png
index e694b54b..ef79aab 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/cascade/cascade_order-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/cascade/cascade_order-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/cascade/important-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/cascade/important-expected.png
index 3de29e8..d846d3f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/cascade/important-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/cascade/important-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/classification/display-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/classification/display-expected.png
index c722fa236..ed2292f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/classification/display-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/classification/display-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style-expected.png
index 60e65d5..c5651f46 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style_image-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style_image-expected.png
index b017aa5..cabfb1b 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style_image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style_position-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style_position-expected.png
index d9c3eba9..0b52d37 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style_position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style_position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style_type-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style_type-expected.png
index 81ede0a..7cb1e12 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style_type-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/classification/list_style_type-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/classification/white_space-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/classification/white_space-expected.png
index df1df56..9e660586 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/classification/white_space-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/classification/white_space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/background_color-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/background_color-expected.png
index 157863b..7c42cd27 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/background_color-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/background_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/background_image-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/background_image-expected.png
index 51565f6..5a8826c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/background_image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/background_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/background_repeat-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/background_repeat-expected.png
index bf456ff..e21d3768 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/background_repeat-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/background_repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/color-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/color-expected.png
index 6fc0975..b45b691 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/color-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/color_and_background/color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/conformance/forward_compatible_parsing-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/conformance/forward_compatible_parsing-expected.png
index c25112d..8cddb1e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/conformance/forward_compatible_parsing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/conformance/forward_compatible_parsing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font-expected.png
index 563c813..12659cd 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_family-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_family-expected.png
index 2e9f43f..a4d3b7e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_family-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_family-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_size-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_size-expected.png
index 412f79fb..2a4839a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_style-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_style-expected.png
index 8639217..4ddfeae9 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_variant-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_variant-expected.png
index 49e02b6..6658e87 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_variant-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_variant-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_weight-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_weight-expected.png
index 9819bde..106e0ec9 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_weight-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/font_properties/font_weight-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/floating_elements-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/floating_elements-expected.png
index ac4b360..dcbf457 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/floating_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/floating_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/height_of_lines-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/height_of_lines-expected.png
index 933b998..c023e4de 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/height_of_lines-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/height_of_lines-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/horizontal_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/horizontal_formatting-expected.png
index 58adac3..3e2252f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/horizontal_formatting-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/horizontal_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/inline_elements-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/inline_elements-expected.png
index 325a77f8..658bfbb 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/inline_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/inline_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/replaced_elements-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/replaced_elements-expected.png
index fac07a90..2f655e3 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/replaced_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/replaced_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/vertical_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/vertical_formatting-expected.png
index ccdfc33..bfabb9fc 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/vertical_formatting-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/formatting_model/vertical_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/anchor-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/anchor-expected.png
index 2cad599..6f5e76f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/anchor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/anchor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/firstletter-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/firstletter-expected.png
index dfe5098..fd5c31a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/firstletter-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/firstletter-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/firstline-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/firstline-expected.png
index 6ee9175..b788255 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/firstline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/firstline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/multiple_pseudo_elements-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/multiple_pseudo_elements-expected.png
index 79b7509..413003a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/multiple_pseudo_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/multiple_pseudo_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/pseudo_elements_in_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/pseudo_elements_in_selectors-expected.png
index 2522337..ad2e13a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/pseudo_elements_in_selectors-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/pseudo/pseudo_elements_in_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/letter_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/letter_spacing-expected.png
index d14bfeb4..893f0066 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/letter_spacing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/letter_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/line_height-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/line_height-expected.png
index dca6c0c..dea724af 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/line_height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/line_height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_align-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_align-expected.png
index 7e87caf..abb8590c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_align-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_decoration-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_decoration-expected.png
index 44daf187..b0f29909 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_decoration-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_decoration-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_indent-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_indent-expected.png
index d44b1d1..e366f8ab 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_indent-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_indent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_transform-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_transform-expected.png
index 29714786..d9d93310 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/text_transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/vertical_align-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/vertical_align-expected.png
index 89dbb74..b342faf4 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/vertical_align-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/vertical_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/word_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/word_spacing-expected.png
index fc2db37..94b5714a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/word_spacing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/text_properties/word_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/units/color_units-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/units/color_units-expected.png
index 0bebd3f..7b13c865 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/units/color_units-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/units/color_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/units/length_units-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/units/length_units-expected.png
index 5948a84..4b913e5 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/units/length_units-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/units/length_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css1/units/percentage_units-expected.png b/third_party/WebKit/LayoutTests/platform/win/css1/units/percentage_units-expected.png
index edc8c87d..6d560863 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css1/units/percentage_units-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css1/units/percentage_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-00-a-ag-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-00-a-ag-expected.png
index 1ca56ab..a87e6160 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-00-a-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-00-a-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-02-d-agi-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-02-d-agi-expected.png
index b702fae..c9b279ac0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-02-d-agi-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-02-d-agi-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-03-d-agi-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-03-d-agi-expected.png
index 21a3af7..29ddf0b0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-03-d-agi-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-03-d-agi-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-04-d-agi-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-04-d-agi-expected.png
index 23c3549..0679e44f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-04-d-agi-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c544-valgn-04-d-agi-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c548-ln-ht-03-d-ag-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c548-ln-ht-03-d-ag-expected.png
index 03b4ce2..88c0780 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c548-ln-ht-03-d-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t100801-c548-ln-ht-03-d-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-00-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-00-c-ag-expected.png
index 9b55a11..6f188f1 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-00-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-00-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-01-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-01-c-ag-expected.png
index 9b55a11..6f188f1 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-01-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-01-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-02-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-02-c-ag-expected.png
index 9b55a11..fb2b838 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-02-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-02-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-03-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-03-c-ag-expected.png
index 9b55a11..c6e7f59 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-03-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-03-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-04-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-04-c-ag-expected.png
index 9b55a11..c6dfb75 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-04-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-04-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-05-c-ag-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-05-c-ag-expected.png
index 9b55a11..0b1e4e3e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-05-c-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t140201-c534-bgreps-05-c-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css2.1/t1605-c545-txttrans-00-b-ag-expected.png b/third_party/WebKit/LayoutTests/platform/win/css2.1/t1605-c545-txttrans-00-b-ag-expected.png
index 04d36d5..dcee8d69 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css2.1/t1605-c545-txttrans-00-b-ag-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css2.1/t1605-c545-txttrans-00-b-ag-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css3/blending/background-blend-mode-tiled-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/win/css3/blending/background-blend-mode-tiled-gradient-expected.png
index 25ce7cf..2a62565d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css3/blending/background-blend-mode-tiled-gradient-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css3/blending/background-blend-mode-tiled-gradient-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css3/masking/mask-luminance-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/win/css3/masking/mask-luminance-gradient-expected.png
new file mode 100644
index 0000000..a798932
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/css3/masking/mask-luminance-gradient-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/css3/masking/mask-repeat-space-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/css3/masking/mask-repeat-space-border-expected.png
index fe24a5c..e6fa3f21 100644
--- a/third_party/WebKit/LayoutTests/platform/win/css3/masking/mask-repeat-space-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/css3/masking/mask-repeat-space-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-repeat-with-background-color-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-repeat-with-background-color-expected.png
index a0567ed..60aa8a1 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-repeat-with-background-color-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-repeat-with-background-color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-svg-scaling-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-svg-scaling-expected.png
index e43aef8..2623ea2 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-svg-scaling-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-svg-scaling-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-svg-scaling-zoom-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-svg-scaling-zoom-expected.png
index d1b2c50..1240738 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-svg-scaling-zoom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/background-svg-scaling-zoom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/border-radius-split-background-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/border-radius-split-background-image-expected.png
index 753d990..b186f93 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/border-radius-split-background-image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/border-radius-split-background-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/repeat/negative-offset-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/repeat/negative-offset-repeat-expected.png
index 82e8cb4..b2ffb47 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/repeat/negative-offset-repeat-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/repeat/negative-offset-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png
index 5a49bbe..b7f674e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/repeat/negative-offset-repeat-transformed-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/size/backgroundSize15-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/size/backgroundSize15-expected.png
index e8d23a2..f4171be 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/size/backgroundSize15-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/backgrounds/size/backgroundSize15-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-01-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-01-expected.png
index 5f65986..3e23a7dc 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-01-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-01-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-border-radius-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-border-radius-expected.png
index 4b75a428..1418bc79 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-border-radius-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-border-radius-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-longhand-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-longhand-expected.png
index 5f65986..3e23a7dc 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-longhand-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-longhand-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-expected.png
index 4f6d27d..fd4cda8e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-in-shorthand-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-in-shorthand-expected.png
index 4f6d27d..fd4cda8e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-in-shorthand-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-in-shorthand-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-split-inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-split-inline-expected.png
index 4559c162..7edc0b2 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-split-inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-outset-split-inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-expected.png
index 5f65986..3e23a7dc 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-round-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-round-expected.png
index 659541e..016ef88 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-round-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-repeat-round-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scrambled-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scrambled-expected.png
index 5f65986..3e23a7dc 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scrambled-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-scrambled-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-slices-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-slices-expected.png
index 5b4456b1..5dc7b50 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-slices-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-slices-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-source-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-source-expected.png
index 5f65986..3e23a7dc 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-source-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/border-image-source-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/borders/scaled-border-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/borders/scaled-border-image-expected.png
index b80f326e..4bd00bd 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/borders/scaled-border-image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/borders/scaled-border-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/canvas/image-object-in-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/canvas/image-object-in-canvas-expected.png
index 9080c8a..e8f71624 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/canvas/image-object-in-canvas-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/canvas/image-object-in-canvas-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/canvas/patternfill-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/canvas/patternfill-repeat-expected.png
new file mode 100644
index 0000000..ccb5637
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/canvas/patternfill-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/canvas/patternfill-repeat-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/canvas/patternfill-repeat-expected.txt
new file mode 100644
index 0000000..6a81b68
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/canvas/patternfill-repeat-expected.txt
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x469
+  LayoutBlockFlow {HTML} at (0,0) size 800x469
+    LayoutBlockFlow {BODY} at (8,16) size 784x437
+      LayoutBlockFlow {P} at (0,0) size 784x80
+        LayoutText {#text} at (0,0) size 778x79
+          text run at (0,0) width 753: "There should be one big square below containing four squares. Top left square should be filled with 3 rows of 2 and bit Apple"
+          text run at (0,20) width 763: "images. Top right square should be 2 and a bit rows with one Apple image column along the left edge of the square. Bottom left"
+          text run at (0,40) width 778: "square should be one row with three Apple images along the top of the square. Bottom right square should be one Apple image in"
+          text run at (0,60) width 89: "top left corner."
+      LayoutBlockFlow {P} at (0,96) size 784x341
+layer at (8,112) size 336x336
+  LayoutHTMLCanvas {CANVAS} at (0,0) size 336x336 [border: (3px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/css/background-image-with-baseurl-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/css/background-image-with-baseurl-expected.png
index e96379e..e633204c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/css/background-image-with-baseurl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/css/background-image-with-baseurl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/css/import_with_baseurl-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/css/import_with_baseurl-expected.png
index e96379e..e633204c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/css/import_with_baseurl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/css/import_with_baseurl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/css/text-overflow-ellipsis-multiple-shadows-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/css/text-overflow-ellipsis-multiple-shadows-expected.png
new file mode 100644
index 0000000..a007bbe
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/css/text-overflow-ellipsis-multiple-shadows-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/css/text-overflow-ellipsis-multiple-shadows-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/css/text-overflow-ellipsis-multiple-shadows-expected.txt
new file mode 100644
index 0000000..302908df
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/css/text-overflow-ellipsis-multiple-shadows-expected.txt
@@ -0,0 +1,9 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x8
+  LayoutBlockFlow {HTML} at (0,0) size 800x8
+    LayoutBlockFlow {BODY} at (8,8) size 784x0
+layer at (0,0) size 144x84 scrollWidth 160
+  LayoutBlockFlow (positioned) {DIV} at (0,0) size 144x84
+    LayoutText {#text} at (0,1) size 160x81
+      text run at (0,1) width 160: "Blink"
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
index 95c08eaf..18e1c6f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
index 00553f98..6ed65d3 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
index c374e2a..5809638 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
index 150bda7..b8b5f0b 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
index 863d01b..5368aa8 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
index 4960f77..d4e6c8ed 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
index 6dbb5dd..a1a0ff15 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-ru-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
index 1aebea6..37e5d5dc 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
index 20dd8b2..8a8e516 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
index 8778c6f..ddf25bf4 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-expected.png
index f1cca80..00feb2c3 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
index 8a01c44..b43ff3f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-expected.png
index 775bef81..6357ff9 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
index eb13873..e406992 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/search/search-appearance-basic-expected.png
index 40c6410..33bafde 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/search/search-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/search/search-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png
index 0d3384e..dc8e805a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/listbox-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.png
index 9fd1b532..829e2ea 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/menulist-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/select-style-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/select-style-expected.png
index 2c655ae..fc2feda 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/select-style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/select/select-style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/submit/submit-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/submit/submit-appearance-basic-expected.png
index 5138c81..74bea00 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/submit/submit-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/submit/submit-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/input-appearance-bkcolor-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/input-appearance-bkcolor-expected.png
index 9a5ade8..2b8c652 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/input-appearance-bkcolor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/input-appearance-bkcolor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/text-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/text-appearance-basic-expected.png
index 36d24a9..aa7aab6 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/text-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/text/text-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/forms/textarea/textarea-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/forms/textarea/textarea-appearance-basic-expected.png
index 5249f8a..a05bb11 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/forms/textarea/textarea-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/forms/textarea/textarea-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/conic-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/conic-gradient-expected.png
index 651581e1..faf1a2e2 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/conic-gradient-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/conic-gradient-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/conic-gradient-out-of-range-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/conic-gradient-out-of-range-expected.png
index 4acadb6..cf33c70 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/conic-gradient-out-of-range-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/conic-gradient-out-of-range-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/conic-gradient-positioning-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/conic-gradient-positioning-expected.png
index 8eb742a4..9c77bf4 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/conic-gradient-positioning-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/conic-gradient-positioning-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/crash-on-zero-radius-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/crash-on-zero-radius-expected.png
index af75602a..a3ec0e9 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/crash-on-zero-radius-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/crash-on-zero-radius-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/repeating-conic-gradient-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/repeating-conic-gradient-expected.png
index 788a23f9..0d31a08 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/repeating-conic-gradient-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/repeating-conic-gradient-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/simple-gradients-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/simple-gradients-expected.png
index df32764..f114b24a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/simple-gradients-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/simple-gradients-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-linear-gradients-color-hints-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-linear-gradients-color-hints-expected.png
index e800143f..8e27d58f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-linear-gradients-color-hints-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-linear-gradients-color-hints-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-radial-gradients-color-hints-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-radial-gradients-color-hints-expected.png
index 7f371dd..77402e7 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-radial-gradients-color-hints-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-radial-gradients-color-hints-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-repeating-gradient-color-hint-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-repeating-gradient-color-hint-expected.png
index 39f10a8..fed2bc9 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-repeating-gradient-color-hint-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/gradients/unprefixed-repeating-gradient-color-hint-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/overflow/overflow-with-local-background-attachment-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/overflow/overflow-with-local-background-attachment-expected.png
index d43cf2e..afa887e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/overflow/overflow-with-local-background-attachment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/overflow/overflow-with-local-background-attachment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index 455d781..7c92da94 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-expected.png
index 529f5e2..dd7a1dd 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-collapsed-border-expected.png
index 985e7f9..967e89ed 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index c4d15e1..72c6569 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-expected.png
index b9c69cfb..327be428 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index 7463edec..517dddf 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-expected.png
index bc391d8..de91bc4f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-expected.png
index 72935ff..214a4af 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index f46c1c00..1497e35 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-expected.png
index db75a6a..2db80f8f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index 7a21863..812a93c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-expected.png
index a2df56b..eac349c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/tbody-background-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/tbody-background-image-expected.png
index 6ca0fd46..f470661 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/table/tbody-background-image-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/tbody-background-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/table/tbody-background-image-repeat-x-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/table/tbody-background-image-repeat-x-expected.png
new file mode 100644
index 0000000..f9cbed3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/table/tbody-background-image-repeat-x-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-lr-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-lr-expected.png
index d159a8a4..fc0ab1f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-lr-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-lr-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-rl-expected.png b/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-rl-expected.png
index 9416c60..6ee82f6 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-rl-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/writing-mode/border-image-vertical-rl-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/win/http/tests/misc/slow-loading-image-in-pattern-expected.png
index 4e798a5..b31909f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/http/tests/misc/slow-loading-image-in-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/http/tests/misc/slow-loading-image-in-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png
index 4685a5c9..0384752d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background-attachment-local-scrolling-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background-repeat-space-padding-box-expected.png b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background-repeat-space-padding-box-expected.png
index bbb908e..f96e0cc2 100644
--- a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background-repeat-space-padding-box-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background-repeat-space-padding-box-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background_repeat_space_border_box-expected.png b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background_repeat_space_border_box-expected.png
index 34016226..40039ee 100644
--- a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background_repeat_space_border_box-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background_repeat_space_border_box-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png
index e469c0e..00b00ae 100644
--- a/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/ietestcenter/css3/bordersbackgrounds/background_repeat_space_content_box-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-clip-text-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-clip-text-expected.png
index cd6c30e..7a9c6d30 100644
--- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-clip-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-clip-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-space-expected.png
index 37132b9d..ff1c5e7e 100644
--- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-space-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-background-image-space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-image-source-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-image-source-expected.png
index 5f65986..3e23a7dc 100644
--- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-image-source-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-border-image-source-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-group-expected.png
index 45a17476..986374b2 100644
--- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-expected.png
index 7dc5cb6..2bd6ec28 100644
--- a/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/images/color-profile-svg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png
index 7ec4ebf..c2a7140d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/images/cross-fade-background-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png
index 03c93a3..2ddeecf4 100644
--- a/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/paint/invalidation/background-image-paint-invalidation-large-abspos-div-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/overflow/fixed-background-scroll-window-expected.png b/third_party/WebKit/LayoutTests/platform/win/paint/overflow/fixed-background-scroll-window-expected.png
new file mode 100644
index 0000000..a2913b1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/paint/overflow/fixed-background-scroll-window-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/paint/overflow/fixed-background-scroll-window-expected.txt b/third_party/WebKit/LayoutTests/platform/win/paint/overflow/fixed-background-scroll-window-expected.txt
new file mode 100644
index 0000000..65dcf66
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/paint/overflow/fixed-background-scroll-window-expected.txt
@@ -0,0 +1,10 @@
+layer at (0,0) size 800x600 scrollY 1000.00 scrollHeight 4016
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x4016 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutBlockFlow {HTML} at (0,0) size 800x4016
+    LayoutBlockFlow {BODY} at (8,8) size 784x4000
+layer at (8,1116) size 622x20 backgroundClip at (0,0) size 800x600 clip at (0,0) size 800x600
+  LayoutBlockFlow (positioned) {P} at (8,1116) size 622x20
+    LayoutText {#text} at (0,0) size 622x19
+      text run at (0,0) width 622: "Tests painting of fixed background content in scrolled container. Passes if the background doesn't scroll."
+scrolled to 0,1000
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png
index 784e9f84..e3cb0e7 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/filters-image-03-f-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/pservers-pattern-04-f-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/pservers-pattern-04-f-expected.png
index f33ccc9c..43e52376 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/pservers-pattern-04-f-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1-SE/pservers-pattern-04-f-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/animate-elem-36-t-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/animate-elem-36-t-expected.png
index ed87cae..c7b0bf5 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/animate-elem-36-t-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/animate-elem-36-t-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/coords-units-01-b-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/coords-units-01-b-expected.png
index fb1b8f2..6202249 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/coords-units-01-b-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/W3C-SVG-1.1/coords-units-01-b-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-expected.png
index 70c5f1a..1ff0b19 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-positioned-objects-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-positioned-objects-expected.png
index 39cf83f9..9ceec58 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-positioned-objects-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/batik/paints/patternRegions-positioned-objects-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textDecoration-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textDecoration-expected.png
index 0a0fd95..2c17b40 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textDecoration-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/batik/text/textDecoration-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/canvas/canvas-default-object-sizing-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/canvas/canvas-default-object-sizing-expected.png
index 3491a4c..617bd636 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/canvas/canvas-default-object-sizing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/canvas/canvas-default-object-sizing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/canvas/canvas-pattern-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/canvas/canvas-pattern-svg-expected.png
index 6237a91..01d54aa 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/canvas/canvas-pattern-svg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/canvas/canvas-pattern-svg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/convolution-crash-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/custom/convolution-crash-expected.png
index 13d4ac1b..85ccba2 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/custom/convolution-crash-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/convolution-crash-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/masking-clipping-hidpi-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/custom/masking-clipping-hidpi-expected.png
index b1896fe7..2f5fcb0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/custom/masking-clipping-hidpi-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/masking-clipping-hidpi-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/pattern-cycle-detection-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/custom/pattern-cycle-detection-expected.png
index 05d58240..9f4c0fb 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/custom/pattern-cycle-detection-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/pattern-cycle-detection-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/pattern-deep-referencing-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/custom/pattern-deep-referencing-expected.png
index 9cd3dd5..e5911d3 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/custom/pattern-deep-referencing-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/pattern-deep-referencing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/pattern-incorrect-tiling-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/custom/pattern-incorrect-tiling-expected.png
index 58eee17..1a52b5c3 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/custom/pattern-incorrect-tiling-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/pattern-incorrect-tiling-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/stroked-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/custom/stroked-pattern-expected.png
index e4b25b8..da23be8 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/custom/stroked-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/stroked-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/transformed-text-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/custom/transformed-text-pattern-expected.png
new file mode 100644
index 0000000..c6ce0d7d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/transformed-text-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/transformed-text-pattern-expected.txt b/third_party/WebKit/LayoutTests/platform/win/svg/custom/transformed-text-pattern-expected.txt
new file mode 100644
index 0000000..b20b253
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/transformed-text-pattern-expected.txt
@@ -0,0 +1,17 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x241
+  LayoutBlockFlow {HTML} at (0,0) size 800x241
+    LayoutBlockFlow {BODY} at (8,8) size 784x225
+      LayoutText {#text} at (0,0) size 307x19
+        text run at (0,0) width 307: "This test passes if there is an A and a green square."
+      LayoutBR {BR} at (307,0) size 0x19
+      LayoutSVGRoot {svg} at (0,20) size 200x200
+        LayoutSVGHiddenContainer {defs} at (0,0) size 0x0
+          LayoutSVGResourcePattern {pattern} [id="pattern"] [patternUnits=userSpaceOnUse] [patternContentUnits=userSpaceOnUse] [patternTransform={m=((10.00,0.00)(0.00,10.00)) t=(0.00,0.00)}]
+            LayoutSVGContainer {g} at (0,40) size 100x70 [transform={m=((0.10,0.00)(0.00,0.10)) t=(0.00,0.00)}]
+              LayoutSVGRect {rect} at (55,55) size 45x45 [fill={[type=SOLID] [color=#008000]}] [x=55.00] [y=55.00] [width=45.00] [height=45.00]
+              LayoutSVGText {text} at (0,40) size 40x70 contains 1 chunk(s)
+                LayoutSVGInlineText {#text} at (0,40) size 40x70
+                  chunk 1 text run 1 at (0.00,100.00) startOffset 0 endOffset 1 width 40.00: "A"
+        LayoutSVGRect {rect} at (0,0) size 400x200 [fill={[type=PATTERN] [id="pattern"]}] [x=0.00] [y=0.00] [width=400.00] [height=200.00]
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/custom/use-on-symbol-inside-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/custom/use-on-symbol-inside-pattern-expected.png
index b55c07fe..41cfed8 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/custom/use-on-symbol-inside-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/custom/use-on-symbol-inside-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/filters/feImage-preserveAspectRatio-all-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/filters/feImage-preserveAspectRatio-all-expected.png
index 79d7522..d7b34fc2 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/filters/feImage-preserveAspectRatio-all-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/filters/feImage-preserveAspectRatio-all-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/text/text-decorations-in-scaled-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/text/text-decorations-in-scaled-pattern-expected.png
index 7fc9defaf..a93cec5 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/text/text-decorations-in-scaled-pattern-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/text/text-decorations-in-scaled-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/transforms/transformed-text-fill-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/transforms/transformed-text-fill-pattern-expected.png
new file mode 100644
index 0000000..547857d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/transforms/transformed-text-fill-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-background-images-expected.png b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-background-images-expected.png
index 6b2859c..c5bd1a72 100644
--- a/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-background-images-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/svg/zoom/page/zoom-background-images-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1067-1-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1067-1-expected.png
index 67a9d53..02560dc 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1067-1-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1067-1-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug12008-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug12008-expected.png
index ae0e469..1289af2 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug12008-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug12008-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1271-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1271-expected.png
deleted file mode 100644
index e88ac21..0000000
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1271-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1296-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1296-expected.png
index 0dc0087..1c683db1 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1296-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1296-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1430-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1430-expected.png
index 1efa670..f109e56 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1430-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla/bugs/bug1430-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/core/backgrounds-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/core/backgrounds-expected.png
index 4698aea5..5c666f0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/core/backgrounds-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/core/backgrounds-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index 283e9a8a..984c31d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/other/test4-expected.png b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/other/test4-expected.png
index 3fffc86..0fe8e6d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/other/test4-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/tables/mozilla_expected_failures/other/test4-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/image-object-in-canvas-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/image-object-in-canvas-expected.png
index 2531a215..e73fe3a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/image-object-in-canvas-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/image-object-in-canvas-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.png
new file mode 100644
index 0000000..ccb5637
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.txt
new file mode 100644
index 0000000..6a81b68
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/display_list_2d_canvas/fast/canvas/patternfill-repeat-expected.txt
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x469
+  LayoutBlockFlow {HTML} at (0,0) size 800x469
+    LayoutBlockFlow {BODY} at (8,16) size 784x437
+      LayoutBlockFlow {P} at (0,0) size 784x80
+        LayoutText {#text} at (0,0) size 778x79
+          text run at (0,0) width 753: "There should be one big square below containing four squares. Top left square should be filled with 3 rows of 2 and bit Apple"
+          text run at (0,20) width 763: "images. Top right square should be 2 and a bit rows with one Apple image column along the left edge of the square. Bottom left"
+          text run at (0,40) width 778: "square should be one row with three Apple images along the top of the square. Bottom right square should be one Apple image in"
+          text run at (0,60) width 89: "top left corner."
+      LayoutBlockFlow {P} at (0,96) size 784x341
+layer at (8,112) size 336x336
+  LayoutHTMLCanvas {CANVAS} at (0,0) size 336x336 [border: (3px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png
index 06894ec..3c7d2da 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-clip-text-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
index 616c9b01..7fea32f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-background-image-space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png
index cf6bd2a7..87a3800 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-border-image-source-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-group-expected.png
index 3eeacaa..eb283fc9 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-expected.png
index b070b93..ea06bfe0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/color-profile-svg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-background-size-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-background-size-expected.png
index 18ce6f4..3abc8c6 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-background-size-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-background-size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png
new file mode 100644
index 0000000..28d7e50
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/patternfill-repeat-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/patternfill-repeat-expected.png
new file mode 100644
index 0000000..0fe9432
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/patternfill-repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/patternfill-repeat-expected.txt b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/patternfill-repeat-expected.txt
new file mode 100644
index 0000000..6a81b68
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/gpu/fast/canvas/patternfill-repeat-expected.txt
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 800x469
+  LayoutBlockFlow {HTML} at (0,0) size 800x469
+    LayoutBlockFlow {BODY} at (8,16) size 784x437
+      LayoutBlockFlow {P} at (0,0) size 784x80
+        LayoutText {#text} at (0,0) size 778x79
+          text run at (0,0) width 753: "There should be one big square below containing four squares. Top left square should be filled with 3 rows of 2 and bit Apple"
+          text run at (0,20) width 763: "images. Top right square should be 2 and a bit rows with one Apple image column along the left edge of the square. Bottom left"
+          text run at (0,40) width 778: "square should be one row with three Apple images along the top of the square. Bottom right square should be one Apple image in"
+          text run at (0,60) width 89: "top left corner."
+      LayoutBlockFlow {P} at (0,96) size 784x341
+layer at (8,112) size 336x336
+  LayoutHTMLCanvas {CANVAS} at (0,0) size 336x336 [border: (3px solid #000000)]
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/comments-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/comments-expected.png
index aaaaf63..41626ca 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/comments-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/comments-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/containment-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/containment-expected.png
index d605a30..63fb91d0 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/containment-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/containment-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/contextual_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/contextual_selectors-expected.png
new file mode 100644
index 0000000..4298466
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/contextual_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/grouping-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/grouping-expected.png
new file mode 100644
index 0000000..1fefd99f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/grouping-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/id_as_selector-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/id_as_selector-expected.png
new file mode 100644
index 0000000..78fa596
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/id_as_selector-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/inheritance-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/inheritance-expected.png
index 05a0dc1..e00fdff 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/inheritance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/basic/inheritance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border-expected.png
index ded3379..6a35cc4 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png
index 9eb228c..040c6ff 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_bottom_inline-expected.png
new file mode 100644
index 0000000..65f0a18
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png
index cdeb031f..12e20a8 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_bottom_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_bottom_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_bottom_width_inline-expected.png
new file mode 100644
index 0000000..3ab4f38
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_bottom_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_color-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_color-expected.png
new file mode 100644
index 0000000..88b119f7f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_color_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_color_inline-expected.png
new file mode 100644
index 0000000..1d064a0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_color_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_inline-expected.png
new file mode 100644
index 0000000..ef0578b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_left-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_left-expected.png
index 7046381..dcbd26ae 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_left_inline-expected.png
new file mode 100644
index 0000000..e521877
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png
index 934737d..dd54e8f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_left_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_left_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_left_width_inline-expected.png
new file mode 100644
index 0000000..bfba7fb4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_left_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_right-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_right-expected.png
new file mode 100644
index 0000000..ce3d48d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png
new file mode 100644
index 0000000..1b7396c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png
index 6ace20de..97681ab 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_right_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_right_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_right_width_inline-expected.png
new file mode 100644
index 0000000..b3003b0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_right_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_style-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_style-expected.png
index 52c9a5b1..ae1ea65 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_style-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png
index 30adad6c..b924c6c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_style_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_top-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_top-expected.png
index 7fae42b..ad05519 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_top-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_top_inline-expected.png
new file mode 100644
index 0000000..de39c94
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png
index 2bc0c02..ab0db171a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_top_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_top_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_top_width_inline-expected.png
new file mode 100644
index 0000000..80f7dc52
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_top_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_width-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_width-expected.png
index 852dcf53..aa12e98 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_width-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_width_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_width_inline-expected.png
new file mode 100644
index 0000000..49f7b2b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/border_width_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/clear-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/clear-expected.png
index 7c3d99fb..df5579bf 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/clear-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/clear-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/clear_float-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/clear_float-expected.png
index 4dcf105..6f4c26c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/clear_float-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/clear_float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/float-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/float-expected.png
new file mode 100644
index 0000000..f1d5b94
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/float-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png
index f5ffaf3c..72420e70 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/float_elements_in_series-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/float_margin-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/float_margin-expected.png
new file mode 100644
index 0000000..1ecfc9b4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/float_margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/float_on_text_elements-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/float_on_text_elements-expected.png
new file mode 100644
index 0000000..7c9c9a0
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/float_on_text_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/height-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/height-expected.png
index 1f789a9..3926c91 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/height-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin-expected.png
new file mode 100644
index 0000000..81a89f5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_bottom-expected.png
new file mode 100644
index 0000000..7ed09181
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_bottom_inline-expected.png
new file mode 100644
index 0000000..2cc03f8
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png
index 5e42be9f..a1c18d4d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_left-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_left-expected.png
index 8243239..e9f4911 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_left_inline-expected.png
new file mode 100644
index 0000000..b1671bd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_right-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_right-expected.png
index 33ca1bcd..551e223d 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_right-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_right_inline-expected.png
new file mode 100644
index 0000000..a25e1bca
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_top-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_top-expected.png
new file mode 100644
index 0000000..c6cef16
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_top_inline-expected.png
new file mode 100644
index 0000000..4a25214
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/margin_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding-expected.png
new file mode 100644
index 0000000..3617bab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_bottom-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_bottom-expected.png
new file mode 100644
index 0000000..49f5b12
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_bottom-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_bottom_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_bottom_inline-expected.png
new file mode 100644
index 0000000..af28062
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_bottom_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png
index 4843da8..2e8ace24 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_left-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_left-expected.png
index d31eecfb..0b10510 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_left-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_left-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_left_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_left_inline-expected.png
new file mode 100644
index 0000000..ef1bb8e7
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_left_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_right-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_right-expected.png
new file mode 100644
index 0000000..6863efc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_right-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_right_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_right_inline-expected.png
new file mode 100644
index 0000000..2d390911
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_right_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_top-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_top-expected.png
new file mode 100644
index 0000000..4939c75
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_top-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_top_inline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_top_inline-expected.png
new file mode 100644
index 0000000..ffc12ba
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/padding_top_inline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/width-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/width-expected.png
new file mode 100644
index 0000000..717281a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/box_properties/width-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/cascade/cascade_order-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/cascade/cascade_order-expected.png
index e694b54b..ef79aab 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/cascade/cascade_order-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/cascade/cascade_order-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/cascade/important-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/cascade/important-expected.png
new file mode 100644
index 0000000..d846d3f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/cascade/important-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/display-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/display-expected.png
index c722fa236..ed2292f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/display-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/display-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/list_style-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/list_style-expected.png
new file mode 100644
index 0000000..c5651f46
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/list_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/list_style_image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/list_style_image-expected.png
new file mode 100644
index 0000000..cabfb1b
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/list_style_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/list_style_position-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/list_style_position-expected.png
index d9c3eba9..0b52d37 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/list_style_position-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/list_style_position-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/list_style_type-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/list_style_type-expected.png
new file mode 100644
index 0000000..7cb1e12
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/list_style_type-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/white_space-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/white_space-expected.png
new file mode 100644
index 0000000..9e660586
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/classification/white_space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/color_and_background/background_color-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/color_and_background/background_color-expected.png
new file mode 100644
index 0000000..7c42cd27
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/color_and_background/background_color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/color_and_background/background_image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/color_and_background/background_image-expected.png
new file mode 100644
index 0000000..5a8826c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/color_and_background/background_image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png
index bf456ff..e21d3768 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/color_and_background/background_repeat-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/color_and_background/color-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/color_and_background/color-expected.png
new file mode 100644
index 0000000..b45b691
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/color_and_background/color-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/conformance/forward_compatible_parsing-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/conformance/forward_compatible_parsing-expected.png
new file mode 100644
index 0000000..8cddb1e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/conformance/forward_compatible_parsing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font-expected.png
new file mode 100644
index 0000000..12659cd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font_family-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font_family-expected.png
new file mode 100644
index 0000000..a4d3b7e
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font_family-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font_size-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font_size-expected.png
new file mode 100644
index 0000000..2a4839a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font_size-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font_style-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font_style-expected.png
new file mode 100644
index 0000000..4ddfeae9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font_style-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font_variant-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font_variant-expected.png
new file mode 100644
index 0000000..6658e87
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font_variant-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font_weight-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font_weight-expected.png
new file mode 100644
index 0000000..106e0ec9
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/font_properties/font_weight-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/floating_elements-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/floating_elements-expected.png
new file mode 100644
index 0000000..dcbf457
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/floating_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/height_of_lines-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/height_of_lines-expected.png
new file mode 100644
index 0000000..c023e4de
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/height_of_lines-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/horizontal_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/horizontal_formatting-expected.png
new file mode 100644
index 0000000..3e2252f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/horizontal_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png
index 325a77f8..658bfbb 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/inline_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/replaced_elements-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/replaced_elements-expected.png
new file mode 100644
index 0000000..2f655e3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/replaced_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/vertical_formatting-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/vertical_formatting-expected.png
new file mode 100644
index 0000000..bfabb9fc
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/formatting_model/vertical_formatting-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/anchor-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/anchor-expected.png
index 2cad599..6f5e76f 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/anchor-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/anchor-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/firstletter-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/firstletter-expected.png
index dfe5098..fd5c31a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/firstletter-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/firstletter-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/firstline-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/firstline-expected.png
index 6ee9175..b788255 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/firstline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/firstline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
index 79b7509..413003a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/pseudo_elements_in_selectors-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/pseudo_elements_in_selectors-expected.png
new file mode 100644
index 0000000..ad2e13a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/pseudo/pseudo_elements_in_selectors-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/letter_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/letter_spacing-expected.png
new file mode 100644
index 0000000..893f0066
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/letter_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/line_height-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/line_height-expected.png
new file mode 100644
index 0000000..dea724af
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/line_height-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/text_align-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/text_align-expected.png
new file mode 100644
index 0000000..abb8590c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/text_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png
index 44daf187..b0f29909 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/text_decoration-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/text_indent-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/text_indent-expected.png
new file mode 100644
index 0000000..e366f8ab
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/text_indent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/text_transform-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/text_transform-expected.png
index 29714786..d9d93310 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/text_transform-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/text_transform-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/vertical_align-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/vertical_align-expected.png
new file mode 100644
index 0000000..b342faf4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/vertical_align-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/word_spacing-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/word_spacing-expected.png
new file mode 100644
index 0000000..94b5714a
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/text_properties/word_spacing-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/units/color_units-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/units/color_units-expected.png
new file mode 100644
index 0000000..7b13c865
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/units/color_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/units/length_units-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/units/length_units-expected.png
new file mode 100644
index 0000000..4b913e5
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/units/length_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/units/percentage_units-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/units/percentage_units-expected.png
new file mode 100644
index 0000000..6d560863
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/css1/units/percentage_units-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index 455d781..7c92da94 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
new file mode 100644
index 0000000..dd7a1dd
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
index 985e7f9..967e89ed 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index c4d15e1..72c6569 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
new file mode 100644
index 0000000..327be428
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index 7463edec..517dddf 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
new file mode 100644
index 0000000..de91bc4f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
new file mode 100644
index 0000000..214a4af
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index f46c1c00..1497e35 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
new file mode 100644
index 0000000..2db80f8f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index 7a21863..812a93c 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
new file mode 100644
index 0000000..eac349c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/tbody-background-image-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/tbody-background-image-expected.png
new file mode 100644
index 0000000..f470661
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/tbody-background-image-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/tbody-background-image-repeat-x-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/tbody-background-image-repeat-x-expected.png
new file mode 100644
index 0000000..f9cbed3
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/fast/table/tbody-background-image-repeat-x-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png
new file mode 100644
index 0000000..b31909f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/mojo-loading/http/tests/misc/slow-loading-image-in-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/off-main-thread-fetch/http/tests/misc/slow-loading-image-in-pattern-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/off-main-thread-fetch/http/tests/misc/slow-loading-image-in-pattern-expected.png
new file mode 100644
index 0000000..b31909f
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/off-main-thread-fetch/http/tests/misc/slow-loading-image-in-pattern-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
index 2ee851d..4a68c33a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png
index 2ee851d..4a68c33a 100644
--- a/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/css1/font_properties/font-expected.png b/third_party/WebKit/LayoutTests/platform/win7/css1/font_properties/font-expected.png
index 99124e79..da15593f 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/css1/font_properties/font-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/css1/font_properties/font-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/css1/font_properties/font_variant-expected.png b/third_party/WebKit/LayoutTests/platform/win7/css1/font_properties/font_variant-expected.png
index 7cd7960..73ebe81 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/css1/font_properties/font_variant-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/css1/font_properties/font_variant-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/css1/pseudo/firstline-expected.png b/third_party/WebKit/LayoutTests/platform/win7/css1/pseudo/firstline-expected.png
index 067e2da5..42d3479d 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/css1/pseudo/firstline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/css1/pseudo/firstline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/css1/pseudo/multiple_pseudo_elements-expected.png b/third_party/WebKit/LayoutTests/platform/win7/css1/pseudo/multiple_pseudo_elements-expected.png
index c417d6e0..e5e79e2 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/css1/pseudo/multiple_pseudo_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/css1/pseudo/multiple_pseudo_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
index c1a464d..34186ebe 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
index 04f5d07..6d209c13 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-coarse-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
index b602735..0c230a0 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
index cb31b24..6a2c770 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-minimum-date-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
index ed34934..f6fdb22e 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-ar-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
index f512a24..989de4d 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-required-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
index 252def7..08f68aa 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
index 8d20f25..fce0e862 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom125-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
index 1a680a5b..77d919b 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/calendar-picker-appearance-zoom200-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-expected.png
index 5c1a1bc..5b23593 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
index d05d4e4..6458b04e 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/month-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-expected.png
index 0fa3f9c6..4fd6774 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-step-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
index ab73edf3..05fe177 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/calendar-picker/week-picker-appearance-step-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/search/search-appearance-basic-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/search/search-appearance-basic-expected.png
index fee1b311..8d361059 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/forms/search/search-appearance-basic-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/forms/search/search-appearance-basic-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index ff92a96..62e93ba 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-expected.png
index f1f0c04..01f13b16 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-collapsed-border-expected.png
index c0e30f5..ae3a576c 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index bcb8114..375001d 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-expected.png
index 5873f63..b2f076d 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index ac61f8a3..819c8653 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-group-expected.png
index c5ceffe..3c847477 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-expected.png
index b9f681d..c841001 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index 73921a6..9efa84b 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-expected.png
index 3e149e71..b511fa0c 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index 7f665e0c..22636dbb 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-group-expected.png
index 7cbd562..387c8d4 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-group-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png b/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
index 5c7358a5..7d1efcd 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/tables/mozilla_expected_failures/marvin/backgr_fixed-bg-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/font_properties/font-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/font_properties/font-expected.png
index 99124e79..da15593f 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/font_properties/font-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/font_properties/font-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/font_properties/font_family-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/font_properties/font_family-expected.png
deleted file mode 100644
index 2e9f43f..0000000
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/font_properties/font_family-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/font_properties/font_variant-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/font_properties/font_variant-expected.png
index 7cd7960..73ebe81 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/font_properties/font_variant-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/font_properties/font_variant-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/pseudo/firstline-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/pseudo/firstline-expected.png
index 067e2da5..42d3479d 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/pseudo/firstline-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/pseudo/firstline-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
index c417d6e0..e5e79e2 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/css1/pseudo/multiple_pseudo_elements-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
index ff92a96..62e93ba 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-cell-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
new file mode 100644
index 0000000..01f13b16
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-cell-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
index c0e30f5..ae3a576c 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
index bcb8114..375001d 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-column-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
new file mode 100644
index 0000000..b2f076d
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-column-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
index ac61f8a3..819c8653 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
new file mode 100644
index 0000000..3c847477
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-column-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
new file mode 100644
index 0000000..c841001
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
index 73921a6..9efa84b 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-row-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
new file mode 100644
index 0000000..b511fa0c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-row-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
index 7f665e0c..22636dbb 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-collapsed-border-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
new file mode 100644
index 0000000..387c8d4
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/mojo-loading/fast/table/backgr_simple-table-row-group-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
index d3f33e5..41369fbe 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200/fast/hidpi/static/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png b/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png
index d3f33e5..41369fbe 100644
--- a/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/win7/virtual/scalefactor200withzoom/fast/hidpi/static/calendar-picker-appearance-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/canvas/canvas-default-object-sizing-expected.png b/third_party/WebKit/LayoutTests/svg/canvas/canvas-default-object-sizing-expected.png
deleted file mode 100644
index 76d02a7..0000000
--- a/third_party/WebKit/LayoutTests/svg/canvas/canvas-default-object-sizing-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/custom/nested-pattern-boundingBoxModeContent-expected.png b/third_party/WebKit/LayoutTests/svg/custom/nested-pattern-boundingBoxModeContent-expected.png
index eb85d525..f16f68ca 100644
--- a/third_party/WebKit/LayoutTests/svg/custom/nested-pattern-boundingBoxModeContent-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/custom/nested-pattern-boundingBoxModeContent-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/custom/pattern-no-pixelation-expected.png b/third_party/WebKit/LayoutTests/svg/custom/pattern-no-pixelation-expected.png
index 071e3b3c..d96dd65 100644
--- a/third_party/WebKit/LayoutTests/svg/custom/pattern-no-pixelation-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/custom/pattern-no-pixelation-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/custom/pattern-referencing-preserve-aspect-ratio-expected.png b/third_party/WebKit/LayoutTests/svg/custom/pattern-referencing-preserve-aspect-ratio-expected.png
index 98fc70da..28779848b 100644
--- a/third_party/WebKit/LayoutTests/svg/custom/pattern-referencing-preserve-aspect-ratio-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/custom/pattern-referencing-preserve-aspect-ratio-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/custom/pattern-scaled-pattern-space-expected.png b/third_party/WebKit/LayoutTests/svg/custom/pattern-scaled-pattern-space-expected.png
index 23ed89f..f0f37fb5c 100644
--- a/third_party/WebKit/LayoutTests/svg/custom/pattern-scaled-pattern-space-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/custom/pattern-scaled-pattern-space-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/custom/pattern-y-offset-expected.png b/third_party/WebKit/LayoutTests/svg/custom/pattern-y-offset-expected.png
index b9418548..37e706aa 100644
--- a/third_party/WebKit/LayoutTests/svg/custom/pattern-y-offset-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/custom/pattern-y-offset-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/custom/transformed-text-pattern-expected.html b/third_party/WebKit/LayoutTests/svg/custom/transformed-text-pattern-expected.html
deleted file mode 100644
index f27218e..0000000
--- a/third_party/WebKit/LayoutTests/svg/custom/transformed-text-pattern-expected.html
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE HTML>
-This test passes if there is an A and a green square.<br>
-<svg xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" width="200px" height="200px">
-    <defs>
-        <pattern id="pattern" patternUnits="userSpaceOnUse" x="0" y="0" width="200px" height="200px" patternTransform="scale(1)">
-            <g transform="scale(1)">
-                <rect width="45px" height="45px" x="55px" y="55px" fill="green"/>
-                <text style="font-size: 60px; font-family: Verdana;" x="0" y="100">A</text>
-            </g>
-        </pattern>
-    </defs>
-    <rect width="400" height="200" x="0" y="0" style="fill:url(#pattern);"/>
-</svg>
\ No newline at end of file
diff --git a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-in-attr-expected.png b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-in-attr-expected.png
index eab1ad8..4a196e4 100644
--- a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-in-attr-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-in-attr-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-kernelUnitLength-attr-expected.png b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-kernelUnitLength-attr-expected.png
index 76e701b..bf354a6a 100644
--- a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-kernelUnitLength-attr-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-kernelUnitLength-attr-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-specularConstant-attr-expected.png b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-specularConstant-attr-expected.png
index eab1ad8..4a196e4 100644
--- a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-specularConstant-attr-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-specularConstant-attr-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-specularExponent-attr-expected.png b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-specularExponent-attr-expected.png
index eab1ad8..4a196e4 100644
--- a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-specularExponent-attr-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-specularExponent-attr-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-suraceScale-attr-expected.png b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-suraceScale-attr-expected.png
index eab1ad8..4a196e4 100644
--- a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-suraceScale-attr-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-dom-suraceScale-attr-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-inherit-lighting-color-css-prop-expected.png b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-inherit-lighting-color-css-prop-expected.png
index e828b3f..335045b 100644
--- a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-inherit-lighting-color-css-prop-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-inherit-lighting-color-css-prop-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-lighting-color-css-prop-expected.png b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-lighting-color-css-prop-expected.png
index e828b3f..335045b 100644
--- a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-lighting-color-css-prop-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-lighting-color-css-prop-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-in-prop-expected.png b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-in-prop-expected.png
index eab1ad8..4a196e4 100644
--- a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-in-prop-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-in-prop-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-specularConstant-prop-expected.png b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-specularConstant-prop-expected.png
index eab1ad8..4a196e4 100644
--- a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-specularConstant-prop-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-specularConstant-prop-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-specularExponent-prop-expected.png b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-specularExponent-prop-expected.png
index eab1ad8..4a196e4 100644
--- a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-specularExponent-prop-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-specularExponent-prop-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-suraceScale-prop-expected.png b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-suraceScale-prop-expected.png
index eab1ad8..4a196e4 100644
--- a/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-suraceScale-prop-expected.png
+++ b/third_party/WebKit/LayoutTests/svg/dynamic-updates/SVGFESpecularLightingElement-svgdom-suraceScale-prop-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/svg/transforms/transformed-text-fill-pattern-expected.html b/third_party/WebKit/LayoutTests/svg/transforms/transformed-text-fill-pattern-expected.html
deleted file mode 100644
index 4df5620..0000000
--- a/third_party/WebKit/LayoutTests/svg/transforms/transformed-text-fill-pattern-expected.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<html><body><svg width="1000" height="600" xmlns="http://www.w3.org/2000/svg">
- <defs>
-   <pattern id="hatch" patternUnits="userSpaceOnUse" x="0" y="0" width="10" height="10">
-     <g style="fill:none; stroke:black; stroke-width:1">
-       <path d="M0,0 l10,10"/>
-       <path d="M10,0 l-10,10"/>
-     </g>
-   </pattern>
-   <clipPath id="clipHack">
-     <rect x="3" y="0" width="24" height="600"></rect>
-     <rect x="33" y="10" width="24" height="600"></rect>
-     <rect x="63" y="0" width="24" height="600"></rect>
-     <rect x="93" y="0" width="24" height="600"></rect>
-     <rect x="123" y="0" width="24" height="600"></rect>
-     <text></text>
-   </clipPath>
- </defs>
- <g transform="scale(4)" clip-path="url(#clipHack)">
-  <rect y="26" width="150" height="30" fill="url(#hatch)">
- </g>
- <g transform="scale(6)" clip-path="url(#clipHack)">
-  <rect y="66" x="0" width="150" height="30" fill="url(#hatch)">
- </g>
-</svg>
-</body>
-</html>
diff --git a/third_party/WebKit/LayoutTests/svg/transforms/transformed-text-fill-pattern-expected.txt b/third_party/WebKit/LayoutTests/svg/transforms/transformed-text-fill-pattern-expected.txt
new file mode 100644
index 0000000..ed889f4a1
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/svg/transforms/transformed-text-fill-pattern-expected.txt
@@ -0,0 +1,29 @@
+layer at (0,0) size 800x600 clip at (0,0) size 785x585 scrollWidth 1008 scrollHeight 616
+  LayoutView at (0,0) size 800x600
+layer at (0,0) size 785x616 backgroundClip at (0,0) size 785x585 clip at (0,0) size 785x585
+  LayoutBlockFlow {HTML} at (0,0) size 785x616
+    LayoutBlockFlow {BODY} at (8,8) size 769x600
+      LayoutSVGRoot {svg} at (0,0) size 1000x600
+        LayoutSVGHiddenContainer {defs} at (0,0) size 0x0
+          LayoutSVGResourcePattern {pattern} [id="hatch"] [patternUnits=userSpaceOnUse] [patternContentUnits=userSpaceOnUse]
+            LayoutSVGContainer {g} at (0,0) size 10x10
+              LayoutSVGPath {path} at (0,0) size 10x10 [stroke={[type=SOLID] [color=#000000]}] [data="M 0 0 l 10 10"]
+              LayoutSVGPath {path} at (0,0) size 10x10 [stroke={[type=SOLID] [color=#000000]}] [data="M 10 0 l -10 10"]
+          LayoutSVGResourceClipper {clipPath} [id="clipHack"] [clipPathUnits=userSpaceOnUse]
+            LayoutSVGRect {rect} at (3,0) size 24x600 [fill={[type=SOLID] [color=#000000]}] [x=3.00] [y=0.00] [width=24.00] [height=600.00]
+            LayoutSVGRect {rect} at (33,10) size 24x600 [fill={[type=SOLID] [color=#000000]}] [x=33.00] [y=10.00] [width=24.00] [height=600.00]
+            LayoutSVGRect {rect} at (63,0) size 24x600 [fill={[type=SOLID] [color=#000000]}] [x=63.00] [y=0.00] [width=24.00] [height=600.00]
+            LayoutSVGRect {rect} at (93,0) size 24x600 [fill={[type=SOLID] [color=#000000]}] [x=93.00] [y=0.00] [width=24.00] [height=600.00]
+            LayoutSVGRect {rect} at (123,0) size 24x600 [fill={[type=SOLID] [color=#000000]}] [x=123.00] [y=0.00] [width=24.00] [height=600.00]
+            LayoutSVGText {text} at (0,0) size 0x0
+        LayoutSVGContainer {g} at (0,26) size 150x30 [transform={m=((4.00,0.00)(0.00,4.00)) t=(0.00,0.00)}]
+          [clipPath="clipHack"] LayoutSVGResourceClipper {clipPath} at (3,0) size 144x610
+          LayoutSVGText {text} at (0,26) size 150x30 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,26) size 150x30
+              chunk 1 text run 1 at (0.00,50.00) startOffset 0 endOffset 5 width 150.00: "AAAAA"
+        LayoutSVGContainer {g} at (0,66) size 150x30 [transform={m=((6.00,0.00)(0.00,6.00)) t=(0.00,0.00)}]
+          [clipPath="clipHack"] LayoutSVGResourceClipper {clipPath} at (3,0) size 144x610
+          LayoutSVGText {text} at (0,66) size 150x30 contains 1 chunk(s)
+            LayoutSVGInlineText {#text} at (0,66) size 150x30
+              chunk 1 text run 1 at (0.00,90.00) startOffset 0 endOffset 5 width 150.00: "AAAAA"
+      LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug1271-expected.png b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug1271-expected.png
new file mode 100644
index 0000000..11eaf2c
--- /dev/null
+++ b/third_party/WebKit/LayoutTests/tables/mozilla/bugs/bug1271-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png
deleted file mode 100644
index a3acd56..0000000
--- a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/cross-fade-overflow-position-expected.png
+++ /dev/null
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/cross-fade-tiled-expected.png b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/cross-fade-tiled-expected.png
index 20fd49a6..2660d01 100644
--- a/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/cross-fade-tiled-expected.png
+++ b/third_party/WebKit/LayoutTests/virtual/exotic-color-space/images/cross-fade-tiled-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/webaudio/OfflineAudioContext/offlineaudiocontext-thread-smoke-test.html b/third_party/WebKit/LayoutTests/webaudio/OfflineAudioContext/offlineaudiocontext-thread-smoke-test.html
index 8834227..37bbe14 100644
--- a/third_party/WebKit/LayoutTests/webaudio/OfflineAudioContext/offlineaudiocontext-thread-smoke-test.html
+++ b/third_party/WebKit/LayoutTests/webaudio/OfflineAudioContext/offlineaudiocontext-thread-smoke-test.html
@@ -19,8 +19,10 @@
       const numberOfChannels = 1;
       const renderLength = 1;
 
-      // Create 2500 contexts in total. 58.0.3029 on OSX crashes around 2030.
-      const maxNumberOfContexts = 2500;
+      // Create 1000 contexts in total. 58.0.3029 on OSX crashes around 2030,
+      // but creating ~2000 threads makes some try bots time-out.
+      // (crbug.com/741699)
+      const maxNumberOfContexts = 1000;
 
       let contexts = [];
 
@@ -40,7 +42,7 @@
       audit.define(
           {
             label: 'context-creation-smoketest',
-            description: 
+            description:
                 'Creating ' + maxNumberOfContexts + ' contexts up front.'
           },
           (task, should) => {
diff --git a/third_party/WebKit/LayoutTests/webshare/share-success.html b/third_party/WebKit/LayoutTests/webshare/share-success.html
index a23f2512..3c56eaa 100644
--- a/third_party/WebKit/LayoutTests/webshare/share-success.html
+++ b/third_party/WebKit/LayoutTests/webshare/share-success.html
@@ -19,11 +19,6 @@
 }, 'successful share');
 
 share_test((t, webshare, mock) => {
-  mock.pushShareResult('', '', '', webshare.ShareError.OK);
-  return callWithKeyDown(() => navigator.share({}));
-}, 'successful share with empty ShareData');
-
-share_test((t, webshare, mock) => {
   const url = '//www.example.com/some/path?some_query#some_fragment';
   mock.pushShareResult('', '', getAbsoluteUrl(url), webshare.ShareError.OK);
   return callWithKeyDown(() => navigator.share({url: url}));
diff --git a/third_party/WebKit/LayoutTests/webshare/share-types.html b/third_party/WebKit/LayoutTests/webshare/share-types.html
index 39789706..cd1d1bb 100644
--- a/third_party/WebKit/LayoutTests/webshare/share-types.html
+++ b/third_party/WebKit/LayoutTests/webshare/share-types.html
@@ -10,16 +10,6 @@
 }
 
 share_test((t, webshare, mock) => {
-  mock.pushShareResult('', '', '', webshare.ShareError.OK);
-  return callWithKeyDown(() => navigator.share(undefined));
-}, 'share of undefined (expect treated as empty dictionary)');
-
-share_test((t, webshare, mock) => {
-  mock.pushShareResult('', '', '', webshare.ShareError.OK);
-  return callWithKeyDown(() => navigator.share(null));
-}, 'share of null (expect treated as empty dictionary)');
-
-share_test((t, webshare, mock) => {
   mock.pushShareResult('true', 'the object', getAbsoluteUrl('384957'), webshare.ShareError.OK);
 
   const objectWithToString = {toString() { return 'the object'; }};
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8EventListenerHelper.cpp b/third_party/WebKit/Source/bindings/core/v8/V8EventListenerHelper.cpp
index 51883ea..66c35636 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8EventListenerHelper.cpp
+++ b/third_party/WebKit/Source/bindings/core/v8/V8EventListenerHelper.cpp
@@ -41,6 +41,8 @@
     v8::Local<v8::Value> value,
     bool is_attribute,
     ListenerLookupType lookup) {
+  RUNTIME_CALL_TIMER_SCOPE(script_state->GetIsolate(),
+                           RuntimeCallStats::CounterId::kGetEventListener);
   if (lookup == kListenerFindOnly) {
     // Used by EventTarget::removeEventListener, specifically
     // EventTargetV8Internal::removeEventListenerMethod
diff --git a/third_party/WebKit/Source/core/dom/Document.idl b/third_party/WebKit/Source/core/dom/Document.idl
index 3a74b3e8..610c2096 100644
--- a/third_party/WebKit/Source/core/dom/Document.idl
+++ b/third_party/WebKit/Source/core/dom/Document.idl
@@ -95,7 +95,7 @@
     [PutForwards=href, Unforgeable] readonly attribute Location? location;
     [RaisesException=Setter] attribute DOMString domain;
     readonly attribute DOMString referrer;
-    [RaisesException] attribute DOMString cookie;
+    [RaisesException, RuntimeCallStatsCounter=DocumentCookie] attribute DOMString cookie;
     readonly attribute DOMString lastModified;
     readonly attribute DocumentReadyState readyState;
 
diff --git a/third_party/WebKit/Source/core/dom/DocumentFragment.cpp b/third_party/WebKit/Source/core/dom/DocumentFragment.cpp
index 6418207..6cafe14 100644
--- a/third_party/WebKit/Source/core/dom/DocumentFragment.cpp
+++ b/third_party/WebKit/Source/core/dom/DocumentFragment.cpp
@@ -25,6 +25,8 @@
 #include "core/dom/Document.h"
 #include "core/html/parser/HTMLDocumentParser.h"
 #include "core/xml/parser/XMLDocumentParser.h"
+#include "platform/bindings/RuntimeCallStats.h"
+#include "platform/bindings/V8PerIsolateData.h"
 
 namespace blink {
 
@@ -67,6 +69,9 @@
 void DocumentFragment::ParseHTML(const String& source,
                                  Element* context_element,
                                  ParserContentPolicy parser_content_policy) {
+  RUNTIME_CALL_TIMER_SCOPE(
+      V8PerIsolateData::MainThreadIsolate(),
+      RuntimeCallStats::CounterId::kDocumentFragmentParseHTML);
   HTMLDocumentParser::ParseDocumentFragment(source, this, context_element,
                                             parser_content_policy);
 }
diff --git a/third_party/WebKit/Source/core/dom/Element.idl b/third_party/WebKit/Source/core/dom/Element.idl
index 67d9dac..64dab21 100644
--- a/third_party/WebKit/Source/core/dom/Element.idl
+++ b/third_party/WebKit/Source/core/dom/Element.idl
@@ -91,7 +91,7 @@
     // CSSOM View Module
     // https://dev.w3.org/csswg/cssom-view/#extension-to-the-element-interface
     DOMRectList getClientRects();
-    DOMRect getBoundingClientRect();
+    [RuntimeCallStatsCounter=ElementGetBoundingClientRect] DOMRect getBoundingClientRect();
 
     // TODO(sunyunjia): Add default value for scrollIntoView() once
     // crbug.com/734599 is fixed.
diff --git a/third_party/WebKit/Source/core/dom/Node.idl b/third_party/WebKit/Source/core/dom/Node.idl
index 9d4a5fd..6c1549e 100644
--- a/third_party/WebKit/Source/core/dom/Node.idl
+++ b/third_party/WebKit/Source/core/dom/Node.idl
@@ -75,7 +75,7 @@
     boolean isDefaultNamespace(DOMString? namespaceURI);
 
     [CEReactions, CustomElementCallbacks, PerWorldBindings, RaisesException] Node insertBefore(Node node, Node? child);
-    [CEReactions, CustomElementCallbacks, PerWorldBindings, RaisesException] Node appendChild(Node node);
+    [CEReactions, CustomElementCallbacks, PerWorldBindings, RaisesException, RuntimeCallStatsCounter=NodeAppendChild] Node appendChild(Node node);
     [CEReactions, CustomElementCallbacks, PerWorldBindings, RaisesException] Node replaceChild(Node node, Node child);
-    [CEReactions, CustomElementCallbacks, RaisesException] Node removeChild(Node child);
+    [CEReactions, CustomElementCallbacks, RaisesException, RuntimeCallStatsCounter=NodeRemoveChild] Node removeChild(Node child);
 };
diff --git a/third_party/WebKit/Source/core/html/canvas/ImageElementBase.cpp b/third_party/WebKit/Source/core/html/canvas/ImageElementBase.cpp
index e3f0bc5d..3e99b09 100644
--- a/third_party/WebKit/Source/core/html/canvas/ImageElementBase.cpp
+++ b/third_party/WebKit/Source/core/html/canvas/ImageElementBase.cpp
@@ -154,6 +154,11 @@
     return ScriptPromise();
   if (!ImageBitmap::IsResizeOptionValid(options, exception_state))
     return ScriptPromise();
+  if (IsSVGSource()) {
+    return ImageBitmap::CreateAsync(this, crop_rect,
+                                    event_target.ToLocalDOMWindow()->document(),
+                                    script_state, options);
+  }
   return ImageBitmapSource::FulfillImageBitmap(
       script_state, ImageBitmap::Create(
                         this, crop_rect,
diff --git a/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.cpp b/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.cpp
index 464bf4a..838cca18 100644
--- a/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.cpp
+++ b/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.cpp
@@ -9,9 +9,11 @@
 #include "core/html/HTMLVideoElement.h"
 #include "core/html/ImageData.h"
 #include "core/offscreencanvas/OffscreenCanvas.h"
+#include "platform/CrossThreadFunctional.h"
 #include "platform/graphics/CanvasColorParams.h"
 #include "platform/graphics/skia/SkiaUtils.h"
 #include "platform/image-decoders/ImageDecoder.h"
+#include "platform/threading/BackgroundTaskRunner.h"
 #include "platform/wtf/CheckedNumeric.h"
 #include "platform/wtf/PtrUtil.h"
 #include "platform/wtf/RefPtr.h"
@@ -36,20 +38,8 @@
 
 namespace {
 
-struct ParsedOptions {
-  bool flip_y = false;
-  bool premultiply_alpha = true;
-  bool should_scale_input = false;
-  unsigned resize_width = 0;
-  unsigned resize_height = 0;
-  IntRect crop_rect;
-  SkFilterQuality resize_quality = kLow_SkFilterQuality;
-  CanvasColorParams color_params;
-  bool color_canvas_extensions_enabled = false;
-};
-
-ParsedOptions DefaultOptions() {
-  return ParsedOptions();
+ImageBitmap::ParsedOptions DefaultOptions() {
+  return ImageBitmap::ParsedOptions();
 }
 
 // The following two functions are helpers used in cropImage
@@ -60,10 +50,10 @@
                  std::max(rect.Height(), -rect.Height()));
 }
 
-ParsedOptions ParseOptions(const ImageBitmapOptions& options,
-                           Optional<IntRect> crop_rect,
-                           IntSize source_size) {
-  ParsedOptions parsed_options;
+ImageBitmap::ParsedOptions ParseOptions(const ImageBitmapOptions& options,
+                                        Optional<IntRect> crop_rect,
+                                        IntSize source_size) {
+  ImageBitmap::ParsedOptions parsed_options;
   if (options.imageOrientation() == kImageOrientationFlipY) {
     parsed_options.flip_y = true;
   } else {
@@ -156,7 +146,7 @@
 // The function dstBufferSizeHasOverflow() is being called at the beginning of
 // each ImageBitmap() constructor, which makes sure that doing
 // width * height * bytesPerPixel will never overflow unsigned.
-bool DstBufferSizeHasOverflow(const ParsedOptions& options) {
+bool DstBufferSizeHasOverflow(const ImageBitmap::ParsedOptions& options) {
   CheckedNumeric<unsigned> total_bytes = options.crop_rect.Width();
   total_bytes *= options.crop_rect.Height();
   total_bytes *=
@@ -213,7 +203,7 @@
     sk_sp<SkImage> input,
     AlphaPremultiplyEnforcement premultiply_enforcement =
         kDontEnforceAlphaPremultiply,
-    const ParsedOptions& options = DefaultOptions()) {
+    const ImageBitmap::ParsedOptions& options = DefaultOptions()) {
   unsigned width = static_cast<unsigned>(input->width());
   unsigned height = static_cast<unsigned>(input->height());
   SkAlphaType alpha_type =
@@ -264,7 +254,7 @@
 }
 
 static void ApplyColorSpaceConversion(sk_sp<SkImage>& image,
-                                      ParsedOptions& options) {
+                                      ImageBitmap::ParsedOptions& options) {
   if (options.color_params.UsesOutputSpaceBlending() &&
       RuntimeEnabledFeatures::ColorCorrectRenderingEnabled()) {
     image = image->makeColorSpace(options.color_params.GetSkColorSpace(),
@@ -322,6 +312,23 @@
   image = colored_image;
 }
 
+static RefPtr<StaticBitmapImage> MakeBlankImage(
+    const ImageBitmap::ParsedOptions& parsed_options,
+    const SkAlphaType alpha_type) {
+  SkImageInfo info = SkImageInfo::Make(
+      parsed_options.crop_rect.Width(), parsed_options.crop_rect.Height(),
+      parsed_options.color_params.GetSkColorType(), alpha_type,
+      parsed_options.color_params.GetSkColorSpace());
+  if (parsed_options.should_scale_input) {
+    info =
+        info.makeWH(parsed_options.resize_width, parsed_options.resize_height);
+  }
+  sk_sp<SkSurface> surface = SkSurface::MakeRaster(info);
+  if (!surface)
+    return nullptr;
+  return StaticBitmapImage::Create(surface->makeImageSnapshot());
+}
+
 sk_sp<SkImage> ImageBitmap::GetSkImageFromDecoder(
     std::unique_ptr<ImageDecoder> decoder,
     SkColorType* decoded_color_type,
@@ -372,7 +379,7 @@
 // need to use the ImageDecoder to decode the image.
 static PassRefPtr<StaticBitmapImage> CropImageAndApplyColorSpaceConversion(
     RefPtr<Image> image,
-    ParsedOptions& parsed_options,
+    ImageBitmap::ParsedOptions& parsed_options,
     AlphaDisposition image_format,
     ColorBehavior color_behavior = ColorBehavior::TransformToGlobalTarget()) {
   DCHECK(image);
@@ -383,18 +390,7 @@
   // return a transparent black image, respecting the color_params but
   // ignoring premultiply_alpha.
   if (src_rect.IsEmpty()) {
-    SkImageInfo info = SkImageInfo::Make(
-        parsed_options.crop_rect.Width(), parsed_options.crop_rect.Height(),
-        parsed_options.color_params.GetSkColorType(), kPremul_SkAlphaType,
-        parsed_options.color_params.GetSkColorSpace());
-    if (parsed_options.should_scale_input) {
-      info = info.makeWH(parsed_options.resize_width,
-                         parsed_options.resize_height);
-    }
-    sk_sp<SkSurface> surface = SkSurface::MakeRaster(info);
-    if (!surface)
-      return nullptr;
-    return StaticBitmapImage::Create(surface->makeImageSnapshot());
+    return MakeBlankImage(parsed_options, kPremul_SkAlphaType);
   }
 
   sk_sp<SkImage> skia_image = image->ImageForCurrentFrame();
@@ -723,7 +719,8 @@
       info = info.makeWH(parsed_options.resize_width,
                          parsed_options.resize_height);
     } else if (crop_rect) {
-      info = info.makeWH(crop_rect->Width(), crop_rect->Height());
+      info = info.makeWH(parsed_options.crop_rect.Width(),
+                         parsed_options.crop_rect.Height());
     } else {
       info = info.makeWH(data->Size().Width(), data->Size().Height());
     }
@@ -947,6 +944,126 @@
                          is_image_bitmap_origin_clean);
 }
 
+void ImageBitmap::ResolvePromiseOnOriginalThread(
+    ScriptPromiseResolver* resolver,
+    sk_sp<SkImage> skia_image,
+    bool origin_clean,
+    std::unique_ptr<ParsedOptions> parsed_options) {
+  DCHECK(IsMainThread());
+  if (!parsed_options->premultiply_alpha) {
+    skia_image =
+        GetSkImageWithAlphaDisposition(skia_image, kDontPremultiplyAlpha);
+  }
+  if (!skia_image) {
+    resolver->Reject(
+        ScriptValue(resolver->GetScriptState(),
+                    v8::Null(resolver->GetScriptState()->GetIsolate())));
+    return;
+  }
+  ApplyColorSpaceConversion(skia_image, *(parsed_options.get()));
+  if (!skia_image) {
+    resolver->Reject(
+        ScriptValue(resolver->GetScriptState(),
+                    v8::Null(resolver->GetScriptState()->GetIsolate())));
+    return;
+  }
+  ImageBitmap* bitmap = new ImageBitmap(StaticBitmapImage::Create(skia_image));
+  if (bitmap && bitmap->BitmapImage()) {
+    bitmap->BitmapImage()->SetOriginClean(origin_clean);
+    bitmap->BitmapImage()->SetPremultiplied(parsed_options->premultiply_alpha);
+  }
+  if (bitmap && bitmap->BitmapImage()) {
+    resolver->Resolve(bitmap);
+  } else {
+    resolver->Reject(
+        ScriptValue(resolver->GetScriptState(),
+                    v8::Null(resolver->GetScriptState()->GetIsolate())));
+  }
+}
+
+void ImageBitmap::RasterizeImageOnBackgroundThread(
+    ScriptPromiseResolver* resolver,
+    sk_sp<PaintRecord> paint_record,
+    const IntRect& dst_rect,
+    bool origin_clean,
+    std::unique_ptr<ParsedOptions> parsed_options) {
+  DCHECK(!IsMainThread());
+  SkImageInfo info = SkImageInfo::Make(
+      dst_rect.Width(), dst_rect.Height(),
+      parsed_options->color_params.GetSkColorType(), kPremul_SkAlphaType);
+  sk_sp<SkSurface> surface = SkSurface::MakeRaster(info);
+  paint_record->Playback(surface->getCanvas());
+  sk_sp<SkImage> skia_image = surface->makeImageSnapshot();
+  RefPtr<WebTaskRunner> task_runner =
+      Platform::Current()->MainThread()->GetWebTaskRunner();
+  task_runner->PostTask(
+      BLINK_FROM_HERE, CrossThreadBind(&ResolvePromiseOnOriginalThread,
+                                       WrapCrossThreadPersistent(resolver),
+                                       std::move(skia_image), origin_clean,
+                                       WTF::Passed(std::move(parsed_options))));
+}
+
+ScriptPromise ImageBitmap::CreateAsync(ImageElementBase* image,
+                                       Optional<IntRect> crop_rect,
+                                       Document* document,
+                                       ScriptState* script_state,
+                                       const ImageBitmapOptions& options) {
+  ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
+  ScriptPromise promise = resolver->Promise();
+
+  RefPtr<Image> input = image->CachedImage()->GetImage();
+  ParsedOptions parsed_options =
+      ParseOptions(options, crop_rect, image->BitmapSourceSize());
+  if (DstBufferSizeHasOverflow(parsed_options)) {
+    resolver->Reject(
+        ScriptValue(resolver->GetScriptState(),
+                    v8::Null(resolver->GetScriptState()->GetIsolate())));
+    return promise;
+  }
+
+  IntRect input_rect(IntPoint(), input->Size());
+  const IntRect src_rect = Intersection(input_rect, parsed_options.crop_rect);
+
+  // In the case when |crop_rect| doesn't intersect the source image, we return
+  // a transparent black image, respecting the color_params but ignoring
+  // poremultiply_alpha.
+  if (src_rect.IsEmpty()) {
+    ImageBitmap* bitmap =
+        new ImageBitmap(MakeBlankImage(parsed_options, kPremul_SkAlphaType));
+    if (bitmap && bitmap->BitmapImage()) {
+      bitmap->BitmapImage()->SetOriginClean(
+          !image->WouldTaintOrigin(document->GetSecurityOrigin()));
+      bitmap->BitmapImage()->SetPremultiplied(parsed_options.premultiply_alpha);
+    }
+    if (bitmap && bitmap->BitmapImage()) {
+      resolver->Resolve(bitmap);
+    } else {
+      resolver->Reject(
+          ScriptValue(resolver->GetScriptState(),
+                      v8::Null(resolver->GetScriptState()->GetIsolate())));
+    }
+    return promise;
+  }
+
+  IntRect draw_src_rect(parsed_options.crop_rect);
+  IntRect draw_dst_rect(0, 0, parsed_options.resize_width,
+                        parsed_options.resize_height);
+  sk_sp<PaintRecord> paint_record =
+      input->PaintRecordForContainer(NullURL(), input->Size(), draw_src_rect,
+                                     draw_dst_rect, parsed_options.flip_y);
+  std::unique_ptr<ParsedOptions> passed_parsed_options =
+      WTF::MakeUnique<ParsedOptions>(parsed_options);
+  BackgroundTaskRunner::PostOnBackgroundThread(
+      BLINK_FROM_HERE,
+      CrossThreadBind(&RasterizeImageOnBackgroundThread,
+                      WrapCrossThreadPersistent(resolver),
+                      std::move(paint_record), draw_dst_rect,
+                      !image->WouldTaintOrigin(document->GetSecurityOrigin()),
+                      WTF::Passed(std::move(passed_parsed_options))));
+
+  return promise;
+}
+
 void ImageBitmap::close() {
   if (!image_ || is_neutered_)
     return;
diff --git a/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.h b/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.h
index 5205177..78e49c2 100644
--- a/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.h
+++ b/third_party/WebKit/Source/core/imagebitmap/ImageBitmap.h
@@ -83,6 +83,12 @@
                              uint32_t height,
                              bool is_image_bitmap_premultiplied,
                              bool is_image_bitmap_origin_clean);
+  static ScriptPromise CreateAsync(
+      ImageElementBase*,
+      Optional<IntRect>,
+      Document*,
+      ScriptState*,
+      const ImageBitmapOptions& = ImageBitmapOptions());
   static sk_sp<SkImage> GetSkImageFromDecoder(
       std::unique_ptr<ImageDecoder>,
       SkColorType* decoded_color_type = nullptr,
@@ -136,6 +142,18 @@
                                   const ImageBitmapOptions&,
                                   ExceptionState&) override;
 
+  struct ParsedOptions {
+    bool flip_y = false;
+    bool premultiply_alpha = true;
+    bool should_scale_input = false;
+    unsigned resize_width = 0;
+    unsigned resize_height = 0;
+    IntRect crop_rect;
+    SkFilterQuality resize_quality = kLow_SkFilterQuality;
+    CanvasColorParams color_params;
+    bool color_canvas_extensions_enabled = false;
+  };
+
   DECLARE_VIRTUAL_TRACE();
 
  private:
@@ -160,7 +178,15 @@
               uint32_t height,
               bool is_image_bitmap_premultiplied,
               bool is_image_bitmap_origin_clean);
-
+  static void ResolvePromiseOnOriginalThread(ScriptPromiseResolver*,
+                                             sk_sp<SkImage>,
+                                             bool origin_clean,
+                                             std::unique_ptr<ParsedOptions>);
+  static void RasterizeImageOnBackgroundThread(ScriptPromiseResolver*,
+                                               sk_sp<PaintRecord>,
+                                               const IntRect&,
+                                               bool origin_clean,
+                                               std::unique_ptr<ParsedOptions>);
   RefPtr<StaticBitmapImage> image_;
   bool is_neutered_ = false;
 };
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol-1.2.json b/third_party/WebKit/Source/core/inspector/browser_protocol-1.2.json
index 1c6f3fd..db58625f 100644
--- a/third_party/WebKit/Source/core/inspector/browser_protocol-1.2.json
+++ b/third_party/WebKit/Source/core/inspector/browser_protocol-1.2.json
@@ -3571,8 +3571,8 @@
                 "name": "dispatchMouseEvent",
                 "parameters": [
                     { "name": "type", "type": "string", "enum": ["mousePressed", "mouseReleased", "mouseMoved"], "description": "Type of the mouse event." },
-                    { "name": "x", "type": "integer", "description": "X coordinate of the event relative to the main frame's viewport."},
-                    { "name": "y", "type": "integer", "description": "Y coordinate of the event relative to the main frame's viewport. 0 refers to the top of the viewport and Y increases as it proceeds towards the bottom of the viewport."},
+                    { "name": "x", "type": "number", "description": "X coordinate of the event relative to the main frame's viewport."},
+                    { "name": "y", "type": "number", "description": "Y coordinate of the event relative to the main frame's viewport. 0 refers to the top of the viewport and Y increases as it proceeds towards the bottom of the viewport."},
                     { "name": "modifiers", "type": "integer", "optional": true, "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0)." },
                     { "name": "timestamp", "type": "number", "optional": true, "description": "Time at which the event occurred. Measured in UTC time in seconds since January 1, 1970 (default: current time)." },
                     { "name": "button", "type": "string", "enum": ["none", "left", "middle", "right"], "optional": true, "description": "Mouse button (default: \"none\")." },
@@ -3613,8 +3613,8 @@
                 "name": "synthesizePinchGesture",
                 "async": true,
                 "parameters": [
-                    { "name": "x", "type": "integer", "description": "X coordinate of the start of the gesture in CSS pixels." },
-                    { "name": "y", "type": "integer", "description": "Y coordinate of the start of the gesture in CSS pixels." },
+                    { "name": "x", "type": "number", "description": "X coordinate of the start of the gesture in CSS pixels." },
+                    { "name": "y", "type": "number", "description": "Y coordinate of the start of the gesture in CSS pixels." },
                     { "name": "scaleFactor", "type": "number", "description": "Relative scale factor after zooming (>1.0 zooms in, <1.0 zooms out)." },
                     { "name": "relativeSpeed", "type": "integer", "optional": true, "description": "Relative pointer speed in pixels per second (default: 800)." },
                     { "name": "gestureSourceType", "$ref": "GestureSourceType", "optional": true, "description": "Which type of input events to be generated (default: 'default', which queries the platform for the preferred input type)." }
@@ -3627,12 +3627,12 @@
                 "name": "synthesizeScrollGesture",
                 "async": true,
                 "parameters": [
-                    { "name": "x", "type": "integer", "description": "X coordinate of the start of the gesture in CSS pixels." },
-                    { "name": "y", "type": "integer", "description": "Y coordinate of the start of the gesture in CSS pixels." },
-                    { "name": "xDistance", "type": "integer", "optional": true, "description": "The distance to scroll along the X axis (positive to scroll left)." },
-                    { "name": "yDistance", "type": "integer", "optional": true, "description": "The distance to scroll along the Y axis (positive to scroll up)." },
-                    { "name": "xOverscroll", "type": "integer", "optional": true, "description": "The number of additional pixels to scroll back along the X axis, in addition to the given distance." },
-                    { "name": "yOverscroll", "type": "integer", "optional": true, "description": "The number of additional pixels to scroll back along the Y axis, in addition to the given distance." },
+                    { "name": "x", "type": "number", "description": "X coordinate of the start of the gesture in CSS pixels." },
+                    { "name": "y", "type": "number", "description": "Y coordinate of the start of the gesture in CSS pixels." },
+                    { "name": "xDistance", "type": "number", "optional": true, "description": "The distance to scroll along the X axis (positive to scroll left)." },
+                    { "name": "yDistance", "type": "number", "optional": true, "description": "The distance to scroll along the Y axis (positive to scroll up)." },
+                    { "name": "xOverscroll", "type": "number", "optional": true, "description": "The number of additional pixels to scroll back along the X axis, in addition to the given distance." },
+                    { "name": "yOverscroll", "type": "number", "optional": true, "description": "The number of additional pixels to scroll back along the Y axis, in addition to the given distance." },
                     { "name": "preventFling", "type": "boolean", "optional": true, "description": "Prevent fling (default: true)." },
                     { "name": "speed", "type": "integer", "optional": true, "description": "Swipe speed in pixels per second (default: 800)." },
                     { "name": "gestureSourceType", "$ref": "GestureSourceType", "optional": true, "description": "Which type of input events to be generated (default: 'default', which queries the platform for the preferred input type)." },
@@ -3648,8 +3648,8 @@
                 "name": "synthesizeTapGesture",
                 "async": true,
                 "parameters": [
-                    { "name": "x", "type": "integer", "description": "X coordinate of the start of the gesture in CSS pixels." },
-                    { "name": "y", "type": "integer", "description": "Y coordinate of the start of the gesture in CSS pixels." },
+                    { "name": "x", "type": "number", "description": "X coordinate of the start of the gesture in CSS pixels." },
+                    { "name": "y", "type": "number", "description": "Y coordinate of the start of the gesture in CSS pixels." },
                     { "name": "duration", "type": "integer", "optional": true, "description": "Duration between touchdown and touchup events in ms (default: 50)." },
                     { "name": "tapCount", "type": "integer", "optional": true, "description": "Number of times to perform the tap (e.g. 2 for double tap, default: 1)." },
                     { "name": "gestureSourceType", "$ref": "GestureSourceType", "optional": true, "description": "Which type of input events to be generated (default: 'default', which queries the platform for the preferred input type)." }
diff --git a/third_party/WebKit/Source/core/inspector/browser_protocol.json b/third_party/WebKit/Source/core/inspector/browser_protocol.json
index 9156182..2651000 100644
--- a/third_party/WebKit/Source/core/inspector/browser_protocol.json
+++ b/third_party/WebKit/Source/core/inspector/browser_protocol.json
@@ -3982,8 +3982,8 @@
                 "name": "dispatchMouseEvent",
                 "parameters": [
                     { "name": "type", "type": "string", "enum": ["mousePressed", "mouseReleased", "mouseMoved"], "description": "Type of the mouse event." },
-                    { "name": "x", "type": "integer", "description": "X coordinate of the event relative to the main frame's viewport."},
-                    { "name": "y", "type": "integer", "description": "Y coordinate of the event relative to the main frame's viewport. 0 refers to the top of the viewport and Y increases as it proceeds towards the bottom of the viewport."},
+                    { "name": "x", "type": "number", "description": "X coordinate of the event relative to the main frame's viewport in CSS pixels."},
+                    { "name": "y", "type": "number", "description": "Y coordinate of the event relative to the main frame's viewport in CSS pixels. 0 refers to the top of the viewport and Y increases as it proceeds towards the bottom of the viewport."},
                     { "name": "modifiers", "type": "integer", "optional": true, "description": "Bit field representing pressed modifier keys. Alt=1, Ctrl=2, Meta/Command=4, Shift=8 (default: 0)." },
                     { "name": "timestamp", "$ref": "TimeSinceEpoch", "optional": true, "description": "Time at which the event occurred." },
                     { "name": "button", "type": "string", "enum": ["none", "left", "middle", "right"], "optional": true, "description": "Mouse button (default: \"none\")." },
@@ -4021,8 +4021,8 @@
             {
                 "name": "synthesizePinchGesture",
                 "parameters": [
-                    { "name": "x", "type": "integer", "description": "X coordinate of the start of the gesture in CSS pixels." },
-                    { "name": "y", "type": "integer", "description": "Y coordinate of the start of the gesture in CSS pixels." },
+                    { "name": "x", "type": "number", "description": "X coordinate of the start of the gesture in CSS pixels." },
+                    { "name": "y", "type": "number", "description": "Y coordinate of the start of the gesture in CSS pixels." },
                     { "name": "scaleFactor", "type": "number", "description": "Relative scale factor after zooming (>1.0 zooms in, <1.0 zooms out)." },
                     { "name": "relativeSpeed", "type": "integer", "optional": true, "description": "Relative pointer speed in pixels per second (default: 800)." },
                     { "name": "gestureSourceType", "$ref": "GestureSourceType", "optional": true, "description": "Which type of input events to be generated (default: 'default', which queries the platform for the preferred input type)." }
@@ -4033,12 +4033,12 @@
             {
                 "name": "synthesizeScrollGesture",
                 "parameters": [
-                    { "name": "x", "type": "integer", "description": "X coordinate of the start of the gesture in CSS pixels." },
-                    { "name": "y", "type": "integer", "description": "Y coordinate of the start of the gesture in CSS pixels." },
-                    { "name": "xDistance", "type": "integer", "optional": true, "description": "The distance to scroll along the X axis (positive to scroll left)." },
-                    { "name": "yDistance", "type": "integer", "optional": true, "description": "The distance to scroll along the Y axis (positive to scroll up)." },
-                    { "name": "xOverscroll", "type": "integer", "optional": true, "description": "The number of additional pixels to scroll back along the X axis, in addition to the given distance." },
-                    { "name": "yOverscroll", "type": "integer", "optional": true, "description": "The number of additional pixels to scroll back along the Y axis, in addition to the given distance." },
+                    { "name": "x", "type": "number", "description": "X coordinate of the start of the gesture in CSS pixels." },
+                    { "name": "y", "type": "number", "description": "Y coordinate of the start of the gesture in CSS pixels." },
+                    { "name": "xDistance", "type": "number", "optional": true, "description": "The distance to scroll along the X axis (positive to scroll left)." },
+                    { "name": "yDistance", "type": "number", "optional": true, "description": "The distance to scroll along the Y axis (positive to scroll up)." },
+                    { "name": "xOverscroll", "type": "number", "optional": true, "description": "The number of additional pixels to scroll back along the X axis, in addition to the given distance." },
+                    { "name": "yOverscroll", "type": "number", "optional": true, "description": "The number of additional pixels to scroll back along the Y axis, in addition to the given distance." },
                     { "name": "preventFling", "type": "boolean", "optional": true, "description": "Prevent fling (default: true)." },
                     { "name": "speed", "type": "integer", "optional": true, "description": "Swipe speed in pixels per second (default: 800)." },
                     { "name": "gestureSourceType", "$ref": "GestureSourceType", "optional": true, "description": "Which type of input events to be generated (default: 'default', which queries the platform for the preferred input type)." },
@@ -4052,8 +4052,8 @@
             {
                 "name": "synthesizeTapGesture",
                 "parameters": [
-                    { "name": "x", "type": "integer", "description": "X coordinate of the start of the gesture in CSS pixels." },
-                    { "name": "y", "type": "integer", "description": "Y coordinate of the start of the gesture in CSS pixels." },
+                    { "name": "x", "type": "number", "description": "X coordinate of the start of the gesture in CSS pixels." },
+                    { "name": "y", "type": "number", "description": "Y coordinate of the start of the gesture in CSS pixels." },
                     { "name": "duration", "type": "integer", "optional": true, "description": "Duration between touchdown and touchup events in ms (default: 50)." },
                     { "name": "tapCount", "type": "integer", "optional": true, "description": "Number of times to perform the tap (e.g. 2 for double tap, default: 1)." },
                     { "name": "gestureSourceType", "$ref": "GestureSourceType", "optional": true, "description": "Which type of input events to be generated (default: 'default', which queries the platform for the preferred input type)." }
diff --git a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
index a7c614d..90683dda 100644
--- a/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
+++ b/third_party/WebKit/Source/core/layout/LayoutBlockFlow.h
@@ -408,6 +408,10 @@
     is_self_collapsing_ = CheckIfIsSelfCollapsingBlock();
   }
 
+  // This function is only public so we can call it from NGBlockNode while we're
+  // still working on LayoutNG.
+  void AddOverflowFromFloats();
+
 #ifndef NDEBUG
   void ShowLineTreeAndMark(const InlineBox* = nullptr,
                            const char* = nullptr,
@@ -431,8 +435,6 @@
   void UpdateBlockChildDirtyBitsBeforeLayout(bool relayout_children,
                                              LayoutBox&);
 
-  void AddOverflowFromFloats();
-
   void ComputeSelfHitTestRects(Vector<LayoutRect>&,
                                const LayoutPoint& layer_offset) const override;
 
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc
index d3a558cb..4b66eef 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -57,7 +57,7 @@
       is_horizontal_writing_mode_(
           blink::IsHorizontalWritingMode(space->WritingMode())),
       space_builder_(space) {
-  container_builder_.MutableUnpositionedFloats() = space->UnpositionedFloats();
+  unpositioned_floats_ = ConstraintSpace().UnpositionedFloats();
 
   if (!is_horizontal_writing_mode_)
     baseline_type_ = FontBaseline::kIdeographicBaseline;
@@ -78,7 +78,7 @@
     NGLogicalOffset origin_point =
         GetOriginPointForFloats(ContainerBfcOffset(), content_size_);
     PositionPendingFloats(origin_point.block_offset, &container_builder_,
-                          MutableConstraintSpace());
+                          &unpositioned_floats_, MutableConstraintSpace());
   }
 
   return true;
@@ -447,23 +447,42 @@
   // border and padding of the container block.
   content_size_ = LayoutUnit();
 
-  // Check if we can resolve the BFC offset.
+  // We can resolve our BFC offset if we aren't an empty inline.
   if (!Node().IsEmptyInline()) {
     DCHECK(!container_builder_.BfcOffset());
     LayoutUnit bfc_block_offset = constraint_space_->BfcOffset().block_offset +
                                   constraint_space_->MarginStrut().Sum();
     MaybeUpdateFragmentBfcOffset(*constraint_space_, bfc_block_offset,
                                  &container_builder_);
-    PositionPendingFloats(bfc_block_offset, &container_builder_,
-                          constraint_space_);
+
+    // If we have unpositioned floats from a previous sibling, we need to abort
+    // our layout, and tell our parent that we now know our BFC offset.
+    if (!unpositioned_floats_.IsEmpty()) {
+      // TODO(ikilpatrick): This should be swapping in its unpositioned floats
+      // before aborting, but as because NGLayoutInputNode::IsInline isn't
+      // stable, we can't do this yet.
+      // container_builder_.SwapUnpositionedFloats(&unpositioned_floats_);
+      return container_builder_.Abort(NGLayoutResult::kBfcOffsetResolved);
+    }
   }
 
   NGLineBreaker line_breaker(Node(), constraint_space_, &container_builder_,
-                             BreakToken());
+                             &unpositioned_floats_, BreakToken());
   NGLineInfo line_info;
   while (line_breaker.NextLine(&line_info, {LayoutUnit(), content_size_}))
     CreateLine(&line_info, line_breaker.CreateBreakToken());
 
+  // Place any remaining floats which couldn't fit on the previous line.
+  // TODO(ikilpatrick): This is duplicated from CreateLine, but flushes any
+  // floats if we didn't create a line-box. Refactor this such that this isn't
+  // needed.
+  if (container_builder_.BfcOffset()) {
+    NGLogicalOffset origin_point =
+        GetOriginPointForFloats(ContainerBfcOffset(), content_size_);
+    PositionPendingFloats(origin_point.block_offset, &container_builder_,
+                          &unpositioned_floats_, MutableConstraintSpace());
+  }
+
   // TODO(kojii): Check if the line box width should be content or available.
   NGLogicalSize size(max_inline_size_, content_size_);
   container_builder_.SetSize(size).SetOverflowSize(size);
@@ -475,6 +494,15 @@
     container_builder_.SetEndMarginStrut(ConstraintSpace().MarginStrut());
   }
 
+  // If we've got any unpositioned floats here, we must be an empty inline
+  // without a BFC offset. We need to pass our unpositioned floats to our next
+  // sibling.
+  if (!unpositioned_floats_.IsEmpty()) {
+    DCHECK(Node().IsEmptyInline());
+    DCHECK(!container_builder_.BfcOffset());
+    container_builder_.SwapUnpositionedFloats(&unpositioned_floats_);
+  }
+
   PropagateBaselinesFromChildren();
 
   return container_builder_.ToBoxFragment();
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.h
index e7a67472..3417275 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.h
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_layout_algorithm.h
@@ -81,6 +81,7 @@
   unsigned is_horizontal_writing_mode_ : 1;
 
   NGConstraintSpaceBuilder space_builder_;
+  Vector<RefPtr<NGUnpositionedFloat>> unpositioned_floats_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc
index 765e4577..ff37b136 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_inline_node.cc
@@ -354,7 +354,11 @@
   NGInlineLayoutAlgorithm algorithm(*this, constraint_space,
                                     ToNGInlineBreakToken(break_token));
   RefPtr<NGLayoutResult> result = algorithm.Layout();
-  CopyFragmentDataToLayoutBox(*constraint_space, result.Get());
+
+  if (result->Status() == NGLayoutResult::kSuccess &&
+      result->UnpositionedFloats().IsEmpty())
+    CopyFragmentDataToLayoutBox(*constraint_space, result.Get());
+
   return result;
 }
 
@@ -373,7 +377,10 @@
       NGPhysicalFragment::NGFragmentType::kFragmentBox, node);
   container_builder.SetBfcOffset(NGLogicalOffset{LayoutUnit(), LayoutUnit()});
 
-  NGLineBreaker line_breaker(node, space.Get(), &container_builder);
+  Vector<RefPtr<NGUnpositionedFloat>> unpositioned_floats;
+  NGLineBreaker line_breaker(node, space.Get(), &container_builder,
+                             &unpositioned_floats);
+
   NGLineInfo line_info;
   LayoutUnit result;
   while (line_breaker.NextLine(&line_info, NGLogicalOffset())) {
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc
index bcea6b9..855d747 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.cc
@@ -56,13 +56,16 @@
 
 }  // namespace
 
-NGLineBreaker::NGLineBreaker(NGInlineNode node,
-                             NGConstraintSpace* space,
-                             NGFragmentBuilder* container_builder,
-                             const NGInlineBreakToken* break_token)
+NGLineBreaker::NGLineBreaker(
+    NGInlineNode node,
+    NGConstraintSpace* space,
+    NGFragmentBuilder* container_builder,
+    Vector<RefPtr<NGUnpositionedFloat>>* unpositioned_floats,
+    const NGInlineBreakToken* break_token)
     : node_(node),
       constraint_space_(space),
       container_builder_(container_builder),
+      unpositioned_floats_(unpositioned_floats),
       item_index_(0),
       offset_(0),
       break_iterator_(node.Text()),
@@ -436,17 +439,20 @@
   // I.e. we may not have come across any text yet, in order to be able to
   // resolve the BFC position.
   bool float_does_not_fit =
-      !HasAvailableWidth() ||
-      position_ + inline_size + margins.InlineSum() > AvailableWidth();
+      (!constraint_space_->FloatsBfcOffset() ||
+       container_builder_->BfcOffset()) &&
+      (!HasAvailableWidth() ||
+       position_ + inline_size + margins.InlineSum() > AvailableWidth());
 
   // Check if we already have a pending float. That's because a float cannot be
   // higher than any block or floated box generated before.
-  if (!container_builder_->UnpositionedFloats().IsEmpty() ||
-      float_does_not_fit) {
-    container_builder_->AddUnpositionedFloat(unpositioned_float);
+  if (!unpositioned_floats_->IsEmpty() || float_does_not_fit) {
+    unpositioned_floats_->push_back(std::move(unpositioned_float));
   } else {
     NGLogicalOffset container_bfc_offset =
-        container_builder_->BfcOffset().value();
+        container_builder_->BfcOffset()
+            ? container_builder_->BfcOffset().value()
+            : constraint_space_->FloatsBfcOffset().value();
     LayoutUnit origin_block_offset =
         container_bfc_offset.block_offset + content_offset_.block_offset;
 
@@ -456,7 +462,8 @@
 
     // We need to recalculate the available_width as the float probably
     // consumed space on the line.
-    UpdateAvailableWidth();
+    if (container_builder_->BfcOffset())
+      UpdateAvailableWidth();
   }
 
   // Floats are already positioned in the container_builder.
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.h b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.h
index 421b5de1..cb3de05 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.h
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker.h
@@ -32,6 +32,7 @@
   NGLineBreaker(NGInlineNode,
                 NGConstraintSpace*,
                 NGFragmentBuilder*,
+                Vector<RefPtr<NGUnpositionedFloat>>*,
                 const NGInlineBreakToken* = nullptr);
   ~NGLineBreaker() {}
   STACK_ALLOCATED();
@@ -96,6 +97,7 @@
   NGInlineNode node_;
   NGConstraintSpace* constraint_space_;
   NGFragmentBuilder* container_builder_;
+  Vector<RefPtr<NGUnpositionedFloat>>* unpositioned_floats_;
   const AtomicString locale_;
   unsigned item_index_;
   unsigned offset_;
diff --git a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc
index f9c37cb..93f1fa85 100644
--- a/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/inline/ng_line_breaker_test.cc
@@ -40,7 +40,10 @@
         NGPhysicalFragment::NGFragmentType::kFragmentBox, node);
     container_builder.SetBfcOffset(NGLogicalOffset{LayoutUnit(), LayoutUnit()});
 
-    NGLineBreaker line_breaker(node, space.Get(), &container_builder);
+    Vector<RefPtr<NGUnpositionedFloat>> unpositioned_floats;
+    NGLineBreaker line_breaker(node, space.Get(), &container_builder,
+                               &unpositioned_floats);
+
     Vector<NGInlineItemResults> lines;
     NGLineInfo line_info;
     while (line_breaker.NextLine(&line_info, NGLogicalOffset()))
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
index b5244aa..64b252d 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.cc
@@ -61,25 +61,21 @@
          content_size >= space.FragmentainerSpaceAvailable();
 }
 
+bool IsEmptyFragment(NGWritingMode writing_mode,
+                     const NGLayoutResult& layout_result) {
+  if (!layout_result.PhysicalFragment())
+    return true;
+
+  NGFragment fragment(writing_mode, layout_result.PhysicalFragment().Get());
+  if (!fragment.BlockSize())
+    return true;
+
+  return false;
+}
+
 }  // namespace
 
-// This struct is used for communicating to a child the position of the
-// previous inflow child.
-struct NGPreviousInflowPosition {
-  LayoutUnit bfc_block_offset;
-  LayoutUnit logical_block_offset;
-  NGMarginStrut margin_strut;
-};
-
-// This strut holds information for the current inflow child. The data is not
-// useful outside of handling this single inflow child.
-struct NGInflowChildData {
-  NGLogicalOffset bfc_offset_estimate;
-  NGMarginStrut margin_strut;
-  NGBoxStrut margins;
-};
-
-void MaybeUpdateFragmentBfcOffset(const NGConstraintSpace& space,
+bool MaybeUpdateFragmentBfcOffset(const NGConstraintSpace& space,
                                   LayoutUnit bfc_block_offset,
                                   NGFragmentBuilder* builder) {
   DCHECK(builder);
@@ -88,24 +84,31 @@
                                   bfc_block_offset};
     AdjustToClearance(space.ClearanceOffset(), &bfc_offset);
     builder->SetBfcOffset(bfc_offset);
+    return true;
   }
+
+  return false;
 }
 
-void PositionPendingFloats(LayoutUnit origin_block_offset,
-                           NGFragmentBuilder* container_builder,
-                           NGConstraintSpace* space) {
-  DCHECK(container_builder->BfcOffset())
+void PositionPendingFloats(
+    LayoutUnit origin_block_offset,
+    NGFragmentBuilder* container_builder,
+    Vector<RefPtr<NGUnpositionedFloat>>* unpositioned_floats,
+    NGConstraintSpace* space) {
+  DCHECK(container_builder->BfcOffset() || space->FloatsBfcOffset())
       << "Parent BFC offset should be known here";
+  LayoutUnit from_block_offset =
+      container_builder->BfcOffset()
+          ? container_builder->BfcOffset().value().block_offset
+          : space->FloatsBfcOffset().value().block_offset;
 
-  const auto& unpositioned_floats = container_builder->UnpositionedFloats();
   const auto positioned_floats = PositionFloats(
-      origin_block_offset, container_builder->BfcOffset().value().block_offset,
-      unpositioned_floats, space);
+      origin_block_offset, from_block_offset, *unpositioned_floats, space);
 
   for (const auto& positioned_float : positioned_floats)
     container_builder->AddPositionedFloat(positioned_float);
 
-  container_builder->MutableUnpositionedFloats().clear();
+  unpositioned_floats->clear();
 }
 
 NGBlockLayoutAlgorithm::NGBlockLayoutAlgorithm(NGBlockNode node,
@@ -199,8 +202,14 @@
   container_builder_.SetDirection(constraint_space_->Direction());
   container_builder_.SetWritingMode(constraint_space_->WritingMode());
   container_builder_.SetSize(size);
-  container_builder_.MutableUnpositionedFloats() =
-      constraint_space_->UnpositionedFloats();
+
+  // If we have a list of unpositioned floats as input to this layout, we'll
+  // need to abort once our BFC offset is resolved. Additionally the
+  // FloatsBfcOffset() must not be present in this case.
+  unpositioned_floats_ = constraint_space_->UnpositionedFloats();
+  abort_when_bfc_resolved_ = !unpositioned_floats_.IsEmpty();
+  if (abort_when_bfc_resolved_)
+    DCHECK(!constraint_space_->FloatsBfcOffset());
 
   NGBlockChildIterator child_iterator(Node().FirstChild(), BreakToken());
   NGBlockChildIterator::Entry entry = child_iterator.NextChild();
@@ -221,8 +230,14 @@
   //   border/padding between them.
   if (border_scrollbar_padding_.block_start) {
     input_bfc_block_offset += input_margin_strut.Sum();
-    MaybeUpdateFragmentBfcOffset(ConstraintSpace(), input_bfc_block_offset,
-                                 &container_builder_);
+    bool updated = MaybeUpdateFragmentBfcOffset(
+        ConstraintSpace(), input_bfc_block_offset, &container_builder_);
+
+    if (updated && abort_when_bfc_resolved_) {
+      container_builder_.SwapUnpositionedFloats(&unpositioned_floats_);
+      return container_builder_.Abort(NGLayoutResult::kBfcOffsetResolved);
+    }
+
     // We reset the block offset here as it may have been effected by clearance.
     input_bfc_block_offset = ContainerBfcOffset().block_offset;
     input_margin_strut = NGMarginStrut();
@@ -242,26 +257,56 @@
 
   input_bfc_block_offset += content_size_;
 
-  NGPreviousInflowPosition previous_inflow_position = {
-      input_bfc_block_offset, content_size_, input_margin_strut};
+  WTF::Optional<NGPreviousInflowPosition> previous_inflow_position =
+      NGPreviousInflowPosition{input_bfc_block_offset, content_size_,
+                               input_margin_strut};
 
   while (child) {
     if (child.IsOutOfFlowPositioned()) {
       DCHECK(!child_break_token);
-      HandleOutOfFlowPositioned(previous_inflow_position, ToNGBlockNode(child));
+      HandleOutOfFlowPositioned(previous_inflow_position.value(),
+                                ToNGBlockNode(child));
     } else if (child.IsFloating()) {
-      HandleFloating(previous_inflow_position, ToNGBlockNode(child),
+      HandleFloating(previous_inflow_position.value(), ToNGBlockNode(child),
                      ToNGBlockBreakToken(child_break_token));
     } else {
-      NGInflowChildData child_data =
-          PrepareChildLayout(previous_inflow_position, child);
+      // TODO(ikilpatrick): Refactor this else branch.
+      WTF::Optional<NGInflowChildData> child_data =
+          PrepareChildLayout(previous_inflow_position.value(), child);
+
+      // If PrepareChildLayout resolved our BFC offset, abort the layout.
+      if (!child_data) {
+        DCHECK(container_builder_.BfcOffset());
+        container_builder_.SwapUnpositionedFloats(&unpositioned_floats_);
+        return container_builder_.Abort(NGLayoutResult::kBfcOffsetResolved);
+      }
+
       RefPtr<NGConstraintSpace> child_space =
-          CreateConstraintSpaceForChild(child, child_data);
+          CreateConstraintSpaceForChild(child, child_data.value());
       RefPtr<NGLayoutResult> layout_result =
           child.Layout(child_space.Get(), child_break_token);
-      previous_inflow_position =
-          FinishChildLayout(*child_space, previous_inflow_position, child_data,
-                            child, layout_result.Get());
+
+      // A child may have aborted its layout if it resolved its BFC offset. If
+      // we don't have a BFC offset yet, we need to propagate the abortion up
+      // to our parent.
+      if (layout_result->Status() == NGLayoutResult::kBfcOffsetResolved &&
+          !container_builder_.BfcOffset()) {
+        MaybeUpdateFragmentBfcOffset(
+            ConstraintSpace(), layout_result->BfcOffset().value().block_offset,
+            &container_builder_);
+        container_builder_.SwapUnpositionedFloats(&unpositioned_floats_);
+        return container_builder_.Abort(NGLayoutResult::kBfcOffsetResolved);
+      }
+
+      previous_inflow_position = FinishChildLayout(
+          *child_space, previous_inflow_position.value(), child_data.value(),
+          child, child_break_token, std::move(layout_result));
+
+      // If FinishChildLayout resolved our BFC offset, abort the layout.
+      if (!previous_inflow_position) {
+        container_builder_.SwapUnpositionedFloats(&unpositioned_floats_);
+        return container_builder_.Abort(NGLayoutResult::kBfcOffsetResolved);
+      }
     }
 
     entry = child_iterator.NextChild();
@@ -272,8 +317,8 @@
       break;
   }
 
-  NGMarginStrut end_margin_strut = previous_inflow_position.margin_strut;
-  LayoutUnit end_bfc_block_offset = previous_inflow_position.bfc_block_offset;
+  NGMarginStrut end_margin_strut = previous_inflow_position->margin_strut;
+  LayoutUnit end_bfc_block_offset = previous_inflow_position->bfc_block_offset;
 
   // Margins collapsing:
   //   Bottom margins of an in-flow block box doesn't collapse with its last
@@ -282,7 +327,7 @@
   if (border_scrollbar_padding_.block_end ||
       ConstraintSpace().IsNewFormattingContext()) {
     content_size_ =
-        std::max(content_size_, previous_inflow_position.logical_block_offset +
+        std::max(content_size_, previous_inflow_position->logical_block_offset +
                                     end_margin_strut.Sum());
     end_margin_strut = NGMarginStrut();
   }
@@ -306,17 +351,20 @@
       ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_);
   container_builder_.SetBlockSize(size.block_size);
 
-  // Layout our absolute and fixed positioned children.
-  NGOutOfFlowLayoutPart(ConstraintSpace(), Style(), &container_builder_).Run();
-
   // Non-empty blocks always know their position in space.
   // TODO(ikilpatrick): This check for a break token seems error prone.
   if (size.block_size || BreakToken()) {
     end_bfc_block_offset += end_margin_strut.Sum();
-    MaybeUpdateFragmentBfcOffset(ConstraintSpace(), end_bfc_block_offset,
-                                 &container_builder_);
+    bool updated = MaybeUpdateFragmentBfcOffset(
+        ConstraintSpace(), end_bfc_block_offset, &container_builder_);
+
+    if (updated && abort_when_bfc_resolved_) {
+      container_builder_.SwapUnpositionedFloats(&unpositioned_floats_);
+      return container_builder_.Abort(NGLayoutResult::kBfcOffsetResolved);
+    }
+
     PositionPendingFloats(end_bfc_block_offset, &container_builder_,
-                          MutableConstraintSpace());
+                          &unpositioned_floats_, MutableConstraintSpace());
   }
 
   // Margins collapsing:
@@ -337,6 +385,20 @@
       ConstraintSpace().HasBlockFragmentation())
     FinalizeForFragmentation();
 
+  // Only layout absolute and fixed children if we aren't going to revisit this
+  // layout.
+  if (unpositioned_floats_.IsEmpty()) {
+    NGOutOfFlowLayoutPart(ConstraintSpace(), Style(), &container_builder_)
+        .Run();
+  }
+
+  // If we have any unpositioned floats at this stage, need to tell our parent
+  // about this, so that we get relayout with a forced BFC offset.
+  if (!unpositioned_floats_.IsEmpty()) {
+    DCHECK(!container_builder_.BfcOffset());
+    container_builder_.SwapUnpositionedFloats(&unpositioned_floats_);
+  }
+
   PropagateBaselinesFromChildren();
 
   return container_builder_.ToBoxFragment();
@@ -372,26 +434,28 @@
   RefPtr<NGUnpositionedFloat> unpositioned_float = NGUnpositionedFloat::Create(
       child_available_size_, child_percentage_size_, origin_inline_offset,
       constraint_space_->BfcOffset().inline_offset, margins, child, token);
-  container_builder_.AddUnpositionedFloat(unpositioned_float);
+  unpositioned_floats_.push_back(std::move(unpositioned_float));
 
   // If there is a break token for a float we must be resuming layout, we must
   // always know our position in the BFC.
   DCHECK(!token || container_builder_.BfcOffset());
 
   // No need to postpone the positioning if we know the correct offset.
-  if (container_builder_.BfcOffset()) {
+  if (container_builder_.BfcOffset() || ConstraintSpace().FloatsBfcOffset()) {
     // Adjust origin point to the margins of the last child.
     // Example: <div style="margin-bottom: 20px"><float></div>
     //          <div style="margin-bottom: 30px"></div>
     LayoutUnit origin_block_offset =
-        previous_inflow_position.bfc_block_offset +
-        previous_inflow_position.margin_strut.Sum();
+        container_builder_.BfcOffset()
+            ? previous_inflow_position.bfc_block_offset +
+                  previous_inflow_position.margin_strut.Sum()
+            : ConstraintSpace().FloatsBfcOffset().value().block_offset;
     PositionPendingFloats(origin_block_offset, &container_builder_,
-                          MutableConstraintSpace());
+                          &unpositioned_floats_, MutableConstraintSpace());
   }
 }
 
-NGInflowChildData NGBlockLayoutAlgorithm::PrepareChildLayout(
+WTF::Optional<NGInflowChildData> NGBlockLayoutAlgorithm::PrepareChildLayout(
     const NGPreviousInflowPosition& previous_inflow_position,
     NGLayoutInputNode child) {
   DCHECK(child);
@@ -405,8 +469,7 @@
 
   bool should_position_pending_floats =
       !child.CreatesNewFormattingContext() &&
-      ClearanceMayAffectLayout(ConstraintSpace(),
-                               container_builder_.UnpositionedFloats(),
+      ClearanceMayAffectLayout(ConstraintSpace(), unpositioned_floats_,
                                child.Style());
 
   // Children which may clear a float need to force all the pending floats to
@@ -414,12 +477,16 @@
   if (should_position_pending_floats) {
     LayoutUnit origin_point_block_offset =
         bfc_block_offset + margin_strut.Sum();
-    MaybeUpdateFragmentBfcOffset(ConstraintSpace(), origin_point_block_offset,
-                                 &container_builder_);
+    bool updated = MaybeUpdateFragmentBfcOffset(
+        ConstraintSpace(), origin_point_block_offset, &container_builder_);
+
+    if (updated && abort_when_bfc_resolved_)
+      return WTF::nullopt;
+
     // TODO(ikilpatrick): Check if origin_point_block_offset is correct -
     // MaybeUpdateFragmentBfcOffset might have changed it due to clearance.
     PositionPendingFloats(origin_point_block_offset, &container_builder_,
-                          MutableConstraintSpace());
+                          &unpositioned_floats_, MutableConstraintSpace());
   }
 
   NGLogicalOffset child_bfc_offset = {
@@ -429,48 +496,79 @@
 
   // Append the current margin strut with child's block start margin.
   // Non empty border/padding, and new FC use cases are handled inside of the
-  // child's layout.
+  // child's layout
   margin_strut.Append(margins.block_start);
 
-  return {child_bfc_offset, margin_strut, margins};
+  return NGInflowChildData{child_bfc_offset, margin_strut, margins};
 }
 
-NGPreviousInflowPosition NGBlockLayoutAlgorithm::FinishChildLayout(
+WTF::Optional<NGPreviousInflowPosition>
+NGBlockLayoutAlgorithm::FinishChildLayout(
     const NGConstraintSpace& child_space,
     const NGPreviousInflowPosition& previous_inflow_position,
     const NGInflowChildData& child_data,
-    const NGLayoutInputNode child,
-    NGLayoutResult* layout_result) {
-  // Pull out unpositioned floats to the current fragment. This may needed if
-  // for example the child fragment could not position its floats because it's
-  // empty and therefore couldn't determine its position in space.
-  container_builder_.MutableUnpositionedFloats().AppendVector(
-      layout_result->UnpositionedFloats());
+    NGLayoutInputNode child,
+    NGBreakToken* child_break_token,
+    RefPtr<NGLayoutResult> layout_result) {
+  // TODO(ikilpatrick): Split this function into two - one for positioning, and
+  // the other for producing NGPreviousInflowPosition.
+
+  // If we don't know our BFC offset yet, we need to copy the list of
+  // unpositioned floats from the child's layout result.
+  //
+  // If the child had any unpositioned floats, we need to abort our layout if
+  // we resolve our BFC offset.
+  //
+  // If we are a new formatting context, the child will get re-laid out once it
+  // has been positioned.
+  //
+  // TODO(ikilpatrick): a more optimal version of this is to set
+  // abort_when_bfc_resolved_, if the child tree _added_ any floats.
+  if (!container_builder_.BfcOffset() &&
+      !child_space.IsNewFormattingContext()) {
+    unpositioned_floats_ = layout_result->UnpositionedFloats();
+    abort_when_bfc_resolved_ |= !layout_result->UnpositionedFloats().IsEmpty();
+    if (child_space.FloatsBfcOffset())
+      DCHECK(layout_result->UnpositionedFloats().IsEmpty());
+  }
+
+  // Determine the fragment's position in the parent space.
+  WTF::Optional<NGLogicalOffset> child_bfc_offset;
+  if (child.CreatesNewFormattingContext()) {
+    if (!PositionNewFc(child, previous_inflow_position, *layout_result,
+                       child_data, child_space, &child_bfc_offset))
+      return WTF::nullopt;
+  } else if (layout_result->BfcOffset()) {
+    if (!PositionWithBfcOffset(layout_result->BfcOffset().value(),
+                               &child_bfc_offset))
+      return WTF::nullopt;
+  } else if (container_builder_.BfcOffset()) {
+    child_bfc_offset =
+        PositionWithParentBfc(child_space, child_data, *layout_result);
+  } else
+    DCHECK(IsEmptyFragment(ConstraintSpace().WritingMode(), *layout_result));
+
+  if ((layout_result->Status() == NGLayoutResult::kBfcOffsetResolved ||
+       !layout_result->UnpositionedFloats().IsEmpty()) &&
+      child_bfc_offset) {
+    RefPtr<NGConstraintSpace> new_child_space =
+        CreateConstraintSpaceForChild(child, child_data, child_bfc_offset);
+    layout_result = child.Layout(new_child_space.Get(), child_break_token);
+  }
 
   NGBoxFragment fragment(
       ConstraintSpace().WritingMode(),
       ToNGPhysicalBoxFragment(layout_result->PhysicalFragment().Get()));
 
-  // Determine the fragment's position in the parent space.
-  WTF::Optional<NGLogicalOffset> child_bfc_offset;
-  if (child.CreatesNewFormattingContext())
-    child_bfc_offset = PositionNewFc(child, previous_inflow_position, fragment,
-                                     child_data, child_space);
-  else if (layout_result->BfcOffset())
-    child_bfc_offset =
-        PositionWithBfcOffset(layout_result->BfcOffset().value());
-  else if (container_builder_.BfcOffset())
-    child_bfc_offset =
-        PositionWithParentBfc(child_space, child_data, *layout_result);
-  else
-    DCHECK(!fragment.BlockSize());
-
   NGLogicalOffset logical_offset =
       CalculateLogicalOffset(child_data.margins, child_bfc_offset);
 
   NGMarginStrut margin_strut = layout_result->EndMarginStrut();
   margin_strut.Append(child_data.margins.block_end);
 
+  // TODO(ikilpatrick): Refactor below such that we don't have to rely on the
+  // if (fragment) ... checks.
+
   // Only modify content_size_ if the fragment's BlockSize is not empty. This is
   // needed to prevent the situation when logical_offset is included in
   // content_size_ for empty blocks. Example:
@@ -478,14 +576,19 @@
   //     <div style="margin-top: 8px"></div>
   //     <div style="margin-top: 10px"></div>
   //   </div>
-  if (fragment.BlockSize())
-    content_size_ = std::max(
-        content_size_, logical_offset.block_offset + fragment.BlockSize());
-  max_inline_size_ = std::max(
-      max_inline_size_, fragment.InlineSize() + child_data.margins.InlineSum() +
-                            border_scrollbar_padding_.InlineSum());
+  if (fragment) {
+    if (fragment.BlockSize()) {
+      content_size_ = std::max(
+          content_size_, logical_offset.block_offset + fragment.BlockSize());
+    }
+    max_inline_size_ =
+        std::max(max_inline_size_, fragment.InlineSize() +
+                                       child_data.margins.InlineSum() +
+                                       border_scrollbar_padding_.InlineSum());
+  }
 
-  container_builder_.AddChild(layout_result, logical_offset);
+  if (fragment)
+    container_builder_.AddChild(layout_result, logical_offset);
 
   // Determine the child's end BFC block offset and logical offset, for the
   // next child to use.
@@ -495,12 +598,13 @@
   if (child_bfc_offset) {
     // TODO(crbug.com/716930): I think the layout_result->BfcOffset() condition
     // here can be removed once we've removed inline splitting.
-    if (fragment.BlockSize() || layout_result->BfcOffset()) {
+    if (fragment && (fragment.BlockSize() || layout_result->BfcOffset())) {
       child_end_bfc_block_offset =
           child_bfc_offset.value().block_offset + fragment.BlockSize();
       logical_block_offset = logical_offset.block_offset + fragment.BlockSize();
     } else {
-      DCHECK_EQ(LayoutUnit(), fragment.BlockSize());
+      DCHECK(IsEmptyFragment(ConstraintSpace().WritingMode(), *layout_result));
+
       child_end_bfc_block_offset = previous_inflow_position.bfc_block_offset;
       logical_block_offset = previous_inflow_position.logical_block_offset;
     }
@@ -509,17 +613,23 @@
     logical_block_offset = LayoutUnit();
   }
 
-  return {child_end_bfc_block_offset, logical_block_offset, margin_strut};
+  return NGPreviousInflowPosition{child_end_bfc_block_offset,
+                                  logical_block_offset, margin_strut};
 }
 
-NGLogicalOffset NGBlockLayoutAlgorithm::PositionNewFc(
+bool NGBlockLayoutAlgorithm::PositionNewFc(
     const NGLayoutInputNode& child,
     const NGPreviousInflowPosition& previous_inflow_position,
-    const NGBoxFragment& fragment,
+    const NGLayoutResult& layout_result,
     const NGInflowChildData& child_data,
-    const NGConstraintSpace& child_space) {
+    const NGConstraintSpace& child_space,
+    WTF::Optional<NGLogicalOffset>* child_bfc_offset) {
   const ComputedStyle& child_style = child.Style();
 
+  NGBoxFragment fragment(
+      ConstraintSpace().WritingMode(),
+      ToNGPhysicalBoxFragment(layout_result.PhysicalFragment().Get()));
+
   LayoutUnit child_bfc_offset_estimate =
       child_data.bfc_offset_estimate.block_offset;
 
@@ -529,7 +639,7 @@
           .SetIsNewFormattingContext(false)
           .ToConstraintSpace(child_space.WritingMode());
   PositionFloats(child_bfc_offset_estimate, child_bfc_offset_estimate,
-                 container_builder_.UnpositionedFloats(), tmp_space.Get());
+                 unpositioned_floats_, tmp_space.Get());
 
   NGLogicalOffset origin_offset = {ConstraintSpace().BfcOffset().inline_offset +
                                        border_scrollbar_padding_.inline_start,
@@ -553,10 +663,14 @@
   child_bfc_offset_estimate += margin_strut.Sum();
 
   // 4. The child's BFC block offset is known here.
-  MaybeUpdateFragmentBfcOffset(ConstraintSpace(), child_bfc_offset_estimate,
-                               &container_builder_);
+  bool updated = MaybeUpdateFragmentBfcOffset(
+      ConstraintSpace(), child_bfc_offset_estimate, &container_builder_);
+
+  if (updated && abort_when_bfc_resolved_)
+    return false;
+
   PositionPendingFloats(child_bfc_offset_estimate, &container_builder_,
-                        MutableConstraintSpace());
+                        &unpositioned_floats_, MutableConstraintSpace());
 
   origin_offset = {ConstraintSpace().BfcOffset().inline_offset +
                        border_scrollbar_padding_.inline_start,
@@ -571,17 +685,25 @@
       MutableConstraintSpace()->Exclusions().get(), child_space.AvailableSize(),
       origin_offset, child_data.margins, fragment.Size());
 
-  return opportunity.offset;
+  *child_bfc_offset = opportunity.offset;
+  return true;
 }
 
-NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithBfcOffset(
-    const NGLogicalOffset& bfc_offset) {
+bool NGBlockLayoutAlgorithm::PositionWithBfcOffset(
+    const NGLogicalOffset& bfc_offset,
+    WTF::Optional<NGLogicalOffset>* child_bfc_offset) {
   LayoutUnit bfc_block_offset = bfc_offset.block_offset;
-  MaybeUpdateFragmentBfcOffset(ConstraintSpace(), bfc_block_offset,
-                               &container_builder_);
+  bool updated = MaybeUpdateFragmentBfcOffset(
+      ConstraintSpace(), bfc_block_offset, &container_builder_);
+
+  if (updated && abort_when_bfc_resolved_)
+    return false;
+
   PositionPendingFloats(bfc_block_offset, &container_builder_,
-                        MutableConstraintSpace());
-  return bfc_offset;
+                        &unpositioned_floats_, MutableConstraintSpace());
+
+  *child_bfc_offset = bfc_offset;
+  return true;
 }
 
 NGLogicalOffset NGBlockLayoutAlgorithm::PositionWithParentBfc(
@@ -590,9 +712,7 @@
     const NGLayoutResult& layout_result) {
   // The child must be an in-flow zero-block-size fragment, use its end margin
   // strut for positioning.
-  NGFragment fragment(ConstraintSpace().WritingMode(),
-                      layout_result.PhysicalFragment().Get());
-  DCHECK_EQ(fragment.BlockSize(), LayoutUnit());
+  DCHECK(IsEmptyFragment(ConstraintSpace().WritingMode(), layout_result));
 
   NGLogicalOffset child_bfc_offset = {
       ConstraintSpace().BfcOffset().inline_offset +
@@ -602,8 +722,6 @@
           layout_result.EndMarginStrut().Sum()};
 
   AdjustToClearance(space.ClearanceOffset(), &child_bfc_offset);
-  PositionPendingFloats(child_bfc_offset.block_offset, &container_builder_,
-                        MutableConstraintSpace());
   return child_bfc_offset;
 }
 
@@ -676,7 +794,8 @@
 
 RefPtr<NGConstraintSpace> NGBlockLayoutAlgorithm::CreateConstraintSpaceForChild(
     const NGLayoutInputNode child,
-    const NGInflowChildData& child_data) {
+    const NGInflowChildData& child_data,
+    const WTF::Optional<NGLogicalOffset> floats_bfc_offset) {
   NGConstraintSpaceBuilder space_builder(MutableConstraintSpace());
   space_builder.SetAvailableSize(child_available_size_)
       .SetPercentageResolutionSize(child_percentage_size_);
@@ -689,11 +808,17 @@
       .SetBfcOffset(child_data.bfc_offset_estimate)
       .SetMarginStrut(child_data.margin_strut);
 
-  if (!is_new_fc) {
-    // This clears the current layout's unpositioned floats as they may be
-    // positioned by the child.
-    space_builder.SetUnpositionedFloats(
-        container_builder_.MutableUnpositionedFloats());
+  if (!container_builder_.BfcOffset() && ConstraintSpace().FloatsBfcOffset()) {
+    space_builder.SetFloatsBfcOffset(
+        NGLogicalOffset{child_data.bfc_offset_estimate.inline_offset,
+                        ConstraintSpace().FloatsBfcOffset()->block_offset});
+  }
+
+  if (floats_bfc_offset)
+    space_builder.SetFloatsBfcOffset(floats_bfc_offset);
+
+  if (!is_new_fc && !floats_bfc_offset) {
+    space_builder.SetUnpositionedFloats(unpositioned_floats_);
   }
 
   if (child.IsInline()) {
@@ -773,4 +898,5 @@
     }
   }
 }
+
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
index b24ab278..3ba176d 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm.h
@@ -18,19 +18,35 @@
 
 class NGConstraintSpace;
 class NGLayoutResult;
-struct NGInflowChildData;
-struct NGPreviousInflowPosition;
+
+// This struct is used for communicating to a child the position of the
+// previous inflow child.
+struct NGPreviousInflowPosition {
+  LayoutUnit bfc_block_offset;
+  LayoutUnit logical_block_offset;
+  NGMarginStrut margin_strut;
+};
+
+// This strut holds information for the current inflow child. The data is not
+// useful outside of handling this single inflow child.
+struct NGInflowChildData {
+  NGLogicalOffset bfc_offset_estimate;
+  NGMarginStrut margin_strut;
+  NGBoxStrut margins;
+};
 
 // Updates the fragment's BFC offset if it's not already set.
-void MaybeUpdateFragmentBfcOffset(const NGConstraintSpace&,
+bool MaybeUpdateFragmentBfcOffset(const NGConstraintSpace&,
                                   LayoutUnit bfc_block_offset,
                                   NGFragmentBuilder* builder);
 
 // Positions pending floats starting from {@origin_block_offset} and relative
 // to container's BFC offset.
-void PositionPendingFloats(LayoutUnit origin_block_offset,
-                           NGFragmentBuilder* container_builder,
-                           NGConstraintSpace* space);
+void PositionPendingFloats(
+    LayoutUnit origin_block_offset,
+    NGFragmentBuilder* container_builder,
+    Vector<RefPtr<NGUnpositionedFloat>>* unpositioned_floats,
+    NGConstraintSpace* space);
 
 // A class for general block layout (e.g. a <div> with no special style).
 // Lays out the children in sequence.
@@ -55,18 +71,21 @@
   // Creates a new constraint space for the current child.
   RefPtr<NGConstraintSpace> CreateConstraintSpaceForChild(
       const NGLayoutInputNode child,
-      const NGInflowChildData& child_data);
+      const NGInflowChildData& child_data,
+      const WTF::Optional<NGLogicalOffset> floats_bfc_offset = WTF::nullopt);
 
   // @return Estimated BFC offset for the "to be layout" child.
-  NGInflowChildData PrepareChildLayout(const NGPreviousInflowPosition&,
-                                       NGLayoutInputNode);
+  WTF::Optional<NGInflowChildData> PrepareChildLayout(
+      const NGPreviousInflowPosition&,
+      NGLayoutInputNode);
 
-  NGPreviousInflowPosition FinishChildLayout(
+  WTF::Optional<NGPreviousInflowPosition> FinishChildLayout(
       const NGConstraintSpace&,
       const NGPreviousInflowPosition& prev_data,
       const NGInflowChildData& child_data,
-      const NGLayoutInputNode child,
-      NGLayoutResult*);
+      NGLayoutInputNode child,
+      NGBreakToken* child_break_token,
+      RefPtr<NGLayoutResult>);
 
   // Positions the fragment that establishes a new formatting context.
   //
@@ -87,14 +106,18 @@
   //    then it will be placed there and we collapse its margin.
   // 2) If #new-fc is too big then we need to clear its position and place it
   //    below #float ignoring its vertical margin.
-  NGLogicalOffset PositionNewFc(const NGLayoutInputNode& child,
-                                const NGPreviousInflowPosition&,
-                                const NGBoxFragment&,
-                                const NGInflowChildData& child_data,
-                                const NGConstraintSpace& child_space);
+  bool PositionNewFc(const NGLayoutInputNode& child,
+                     const NGPreviousInflowPosition&,
+                     const NGLayoutResult&,
+                     const NGInflowChildData& child_data,
+                     const NGConstraintSpace& child_space,
+                     WTF::Optional<NGLogicalOffset>* child_bfc_offset);
 
   // Positions the fragment that knows its BFC offset.
-  NGLogicalOffset PositionWithBfcOffset(const NGLogicalOffset& bfc_offset);
+  WTF::Optional<NGLogicalOffset> PositionWithBfcOffset(
+      const NGLogicalOffset& bfc_offset);
+  bool PositionWithBfcOffset(const NGLogicalOffset& bfc_offset,
+                             WTF::Optional<NGLogicalOffset>* child_bfc_offset);
 
   // Positions using the parent BFC offset.
   // Fragment doesn't know its offset but we can still calculate its BFC
@@ -137,6 +160,10 @@
   NGBoxStrut border_scrollbar_padding_;
   LayoutUnit content_size_;
   LayoutUnit max_inline_size_;
+
+  bool abort_when_bfc_resolved_;
+
+  Vector<RefPtr<NGUnpositionedFloat>> unpositioned_floats_;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
index fdb1e5d5..a774fe4 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_layout_algorithm_test.cc
@@ -872,16 +872,16 @@
   int empty2_inline_offset = 35;
   EXPECT_THAT(empty2_fragment->Offset().left, LayoutUnit(empty2_inline_offset));
 
-  ASSERT_EQ(2UL, container_fragment->PositionedFloats().size());
+  ASSERT_EQ(2UL, empty2_fragment->PositionedFloats().size());
   RefPtr<NGPhysicalFragment> left_float_fragment =
-      container_fragment->PositionedFloats().at(0).fragment;
+      empty2_fragment->PositionedFloats().at(0).fragment;
   // inline 25 = empty2's padding(15) + left float's margin(10)
   // block 10 = left float's margin
   EXPECT_THAT(left_float_fragment->Offset(),
               NGPhysicalOffset(LayoutUnit(25), LayoutUnit(10)));
 
   auto right_float_fragment =
-      container_fragment->PositionedFloats().at(1).fragment;
+      empty2_fragment->PositionedFloats().at(1).fragment;
   LayoutUnit right_float_offset = LayoutUnit(125);
   // inline offset 150 = empty2's padding(15) + right float's margin(10) + right
   // float offset(125)
@@ -900,26 +900,24 @@
   EXPECT_THAT(left_float->OffsetTop(), body_top_offset + 10);
 
   // ** Legacy Floating objects **
-  // #container is the 1st non-empty block so floats are attached to it.
-  Element* container = GetDocument().getElementById("container");
+  Element* empty2 = GetDocument().getElementById("empty2");
   auto& floating_objects =
       const_cast<FloatingObjects*>(
-          ToLayoutBlockFlow(container->GetLayoutObject())->GetFloatingObjects())
+          ToLayoutBlockFlow(empty2->GetLayoutObject())->GetFloatingObjects())
           ->MutableSet();
   ASSERT_EQ(2UL, floating_objects.size());
   auto left_floating_object = floating_objects.TakeFirst();
   ASSERT_TRUE(left_floating_object->IsPlaced());
   // 80 = float_inline_offset(25) + accumulative offset of empty blocks(35 + 20)
-  EXPECT_THAT(left_floating_object->X(), LayoutUnit(80));
+  EXPECT_THAT(left_floating_object->X(), LayoutUnit(25));
   // 10 = left float's margin
   EXPECT_THAT(left_floating_object->Y(), LayoutUnit(10));
 
   auto right_floating_object = floating_objects.TakeFirst();
   ASSERT_TRUE(right_floating_object->IsPlaced());
-  // 205 = float_inline_offset(25) +
-  //       accumulative offset of empty blocks(35 + 20)
-  //       + right float offset(125)
-  EXPECT_THAT(right_floating_object->X(), LayoutUnit(80) + right_float_offset);
+  // 150 = float_inline_offset(25) +
+  //       right float offset(125)
+  EXPECT_THAT(right_floating_object->X(), LayoutUnit(150));
   // 15 = right float's margin
   EXPECT_THAT(right_floating_object->Y(), LayoutUnit(15));
 }
@@ -986,10 +984,7 @@
   auto* container_fragment =
       ToNGPhysicalBoxFragment(body_fragment->Children()[0].Get());
   ASSERT_EQ(1UL, container_fragment->Children().size());
-  auto* regular_fragment =
-      ToNGPhysicalBoxFragment(container_fragment->Children()[0].Get());
-  ASSERT_EQ(2UL, container_fragment->PositionedFloats().size());
-  ASSERT_EQ(2UL, regular_fragment->PositionedFloats().size());
+  ASSERT_EQ(4UL, container_fragment->PositionedFloats().size());
 
   // ** Verify layout tree **
   Element* left_float = GetDocument().getElementById("left-float");
@@ -997,7 +992,7 @@
   int left_float_block_offset = 8;
   EXPECT_EQ(left_float_block_offset, left_float->OffsetTop());
   auto left_float_fragment =
-      regular_fragment->PositionedFloats().at(0).fragment;
+      container_fragment->PositionedFloats().at(0).fragment;
   EXPECT_THAT(LayoutUnit(), left_float_fragment->Offset().top);
 
   Element* left_wide_float = GetDocument().getElementById("left-wide-float");
@@ -1007,7 +1002,7 @@
   int left_wide_float_block_offset = 38;
   EXPECT_EQ(left_wide_float_block_offset, left_wide_float->OffsetTop());
   auto left_wide_float_fragment =
-      regular_fragment->PositionedFloats().at(1).fragment;
+      container_fragment->PositionedFloats().at(1).fragment;
   // 30 = left-float's height.
   EXPECT_THAT(LayoutUnit(30), left_wide_float_fragment->Offset().top);
 
@@ -1028,7 +1023,7 @@
   EXPECT_EQ(right_float_inline_offset, right_float->OffsetLeft());
   EXPECT_EQ(right_float_block_offset, right_float->OffsetTop());
   auto right_float_fragment =
-      container_fragment->PositionedFloats().at(0).fragment;
+      container_fragment->PositionedFloats().at(2).fragment;
   // 60 = right_float_block_offset(68) - body's margin(8)
   EXPECT_THAT(LayoutUnit(right_float_block_offset - 8),
               right_float_fragment->Offset().top);
@@ -1048,7 +1043,7 @@
   EXPECT_EQ(left_float_with_margin_block_offset,
             left_float_with_margin->OffsetTop());
   auto left_float_with_margin_fragment =
-      container_fragment->PositionedFloats().at(1).fragment;
+      container_fragment->PositionedFloats().at(3).fragment;
   // 70 = left_float_with_margin_block_offset(78) - body's margin(8)
   EXPECT_THAT(LayoutUnit(left_float_with_margin_block_offset - 8),
               left_float_with_margin_fragment->Offset().top);
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
index 6fea69c..b93e9372 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_block_node.cc
@@ -132,7 +132,10 @@
   RefPtr<NGLayoutResult> layout_result =
       LayoutWithAlgorithm(Style(), *this, constraint_space, break_token);
 
-  CopyFragmentDataToLayoutBox(*constraint_space, layout_result.Get());
+  if (layout_result->Status() == NGLayoutResult::kSuccess &&
+      layout_result->UnpositionedFloats().IsEmpty())
+    CopyFragmentDataToLayoutBox(*constraint_space, layout_result.Get());
+
   return layout_result;
 }
 
@@ -280,10 +283,16 @@
     if (child_fragment->IsPlaced())
       FragmentPositionUpdated(ToNGPhysicalBoxFragment(*child_fragment));
 
-    for (const NGPositionedFloat& positioned_float :
-         ToNGPhysicalBoxFragment(child_fragment.Get())->PositionedFloats()) {
-      FloatingObjectPositionedUpdated(
-          positioned_float, ToLayoutBox(child_fragment->GetLayoutObject()));
+    if (child_fragment->GetLayoutObject()->IsLayoutBlockFlow())
+      ToLayoutBlockFlow(child_fragment->GetLayoutObject())
+          ->AddOverflowFromFloats();
+
+    if (child_fragment->GetLayoutObject() == box_) {
+      for (const NGPositionedFloat& positioned_float :
+           ToNGPhysicalBoxFragment(child_fragment.Get())->PositionedFloats()) {
+        FloatingObjectPositionedUpdated(
+            positioned_float, ToLayoutBox(child_fragment->GetLayoutObject()));
+      }
     }
   }
 
@@ -300,7 +309,11 @@
   box_->ClearNeedsLayout();
 
   if (box_->IsLayoutBlockFlow()) {
-    ToLayoutBlockFlow(box_)->UpdateIsSelfCollapsing();
+    LayoutBlockFlow* block_flow = ToLayoutBlockFlow(box_);
+    block_flow->UpdateIsSelfCollapsing();
+
+    if (block_flow->CreatesNewFormattingContext())
+      block_flow->AddOverflowFromFloats();
   }
 }
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
index c4b3ac7..5f3f92b 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.cc
@@ -102,8 +102,15 @@
     fixed_block = true;
   }
 
-  bool is_new_fc =
-      box.IsLayoutBlock() && ToLayoutBlock(box).CreatesNewFormattingContext();
+  bool is_new_fc = true;
+  // TODO(ikilpatrick): This DCHECK needs to be enabled once we've switched
+  // LayoutTableCell, etc over to LayoutNG.
+  //
+  // We currently need to "force" LayoutNG roots to be formatting contexts so
+  // that floats have layout performed on them.
+  //
+  // DCHECK(is_new_fc,
+  //  box.IsLayoutBlock() && ToLayoutBlock(box).CreatesNewFormattingContext());
 
   FloatSize icb_float_size = box.View()->ViewportSizeForViewportUnits();
   NGPhysicalSize initial_containing_block_size{
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
index 21fe728..991f2ff 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space.h
@@ -148,7 +148,7 @@
     return floats_bfc_offset_;
   }
 
-  Vector<RefPtr<NGUnpositionedFloat>>& UnpositionedFloats() {
+  const Vector<RefPtr<NGUnpositionedFloat>>& UnpositionedFloats() const {
     return unpositioned_floats_;
   }
 
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.cc
index 89880d1b..39b0537 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.cc
@@ -145,7 +145,7 @@
 
 NGConstraintSpaceBuilder& NGConstraintSpaceBuilder::SetUnpositionedFloats(
     Vector<RefPtr<NGUnpositionedFloat>>& unpositioned_floats) {
-  unpositioned_floats_.swap(unpositioned_floats);
+  unpositioned_floats_ = unpositioned_floats;
   return *this;
 }
 
@@ -210,10 +210,10 @@
   WTF::Optional<NGLogicalOffset> floats_bfc_offset =
       is_new_fc_ ? WTF::nullopt : floats_bfc_offset_;
 
-  // The inline_offsets of the bfc_offset and floats_bfc_offset should match.
-  if (floats_bfc_offset)
-    DCHECK_EQ(bfc_offset.inline_offset,
-              floats_bfc_offset.value().inline_offset);
+  if (floats_bfc_offset) {
+    floats_bfc_offset = NGLogicalOffset(
+        {bfc_offset.inline_offset, floats_bfc_offset.value().block_offset});
+  }
 
   if (is_in_parallel_flow) {
     return AdoptRef(new NGConstraintSpace(
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment.h
index fd44298f..eb11d50 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_fragment.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment.h
@@ -28,6 +28,9 @@
     return static_cast<NGWritingMode>(writing_mode_);
   }
 
+  // TODO(ikilpatrick): Remove once block layout algorithm refactoring complete.
+  explicit operator bool() { return physical_fragment_ != nullptr; }
+
   // Returns the border-box size.
   LayoutUnit InlineSize() const;
   LayoutUnit BlockSize() const;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
index edf3598..d5622b2 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.cc
@@ -148,12 +148,6 @@
   return *this;
 }
 
-NGFragmentBuilder& NGFragmentBuilder::AddUnpositionedFloat(
-    RefPtr<NGUnpositionedFloat> unpositioned_float) {
-  unpositioned_floats_.push_back(std::move(unpositioned_float));
-  return *this;
-}
-
 void NGFragmentBuilder::GetAndClearOutOfFlowDescendantCandidates(
     Vector<NGOutOfFlowPositionedDescendant>* descendant_candidates) {
   DCHECK(descendant_candidates->IsEmpty());
@@ -239,9 +233,16 @@
       children_, positioned_floats_, baselines_,
       border_edges_.ToPhysical(writing_mode_), std::move(break_token)));
 
-  return AdoptRef(
-      new NGLayoutResult(std::move(fragment), oof_positioned_descendants_,
-                         unpositioned_floats_, bfc_offset_, end_margin_strut_));
+  return AdoptRef(new NGLayoutResult(
+      std::move(fragment), oof_positioned_descendants_, unpositioned_floats_,
+      bfc_offset_, end_margin_strut_, NGLayoutResult::kSuccess));
+}
+
+RefPtr<NGLayoutResult> NGFragmentBuilder::Abort(
+    NGLayoutResult::NGLayoutResultStatus status) {
+  return AdoptRef(new NGLayoutResult(
+      nullptr, Vector<NGOutOfFlowPositionedDescendant>(), unpositioned_floats_,
+      bfc_offset_, end_margin_strut_, status));
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
index 056871f9..2eafa4f5 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_fragment_builder.h
@@ -10,6 +10,7 @@
 #include "core/layout/ng/inline/ng_physical_text_fragment.h"
 #include "core/layout/ng/ng_break_token.h"
 #include "core/layout/ng/ng_constraint_space.h"
+#include "core/layout/ng/ng_layout_result.h"
 #include "core/layout/ng/ng_out_of_flow_positioned_descendant.h"
 #include "core/layout/ng/ng_physical_fragment.h"
 #include "core/layout/ng/ng_positioned_float.h"
@@ -18,8 +19,6 @@
 
 namespace blink {
 
-class NGLayoutResult;
-
 class CORE_EXPORT NGFragmentBuilder final {
   DISALLOW_NEW();
 
@@ -51,9 +50,6 @@
 
   NGFragmentBuilder& SetBfcOffset(const NGLogicalOffset& offset);
 
-  NGFragmentBuilder& AddUnpositionedFloat(
-      RefPtr<NGUnpositionedFloat> unpositioned_float);
-
   // Builder has non-trivial out-of-flow descendant methods.
   // These methods are building blocks for implementation of
   // out-of-flow descendants by layout algorithms.
@@ -108,18 +104,13 @@
   // Creates the fragment. Can only be called once.
   RefPtr<NGLayoutResult> ToBoxFragment();
 
-  Vector<RefPtr<NGPhysicalFragment>>& MutableChildren() { return children_; }
+  RefPtr<NGLayoutResult> Abort(NGLayoutResult::NGLayoutResultStatus);
 
   Vector<NGLogicalOffset>& MutableOffsets() { return offsets_; }
 
-  // Mutable list of floats that need to be positioned.
-  Vector<RefPtr<NGUnpositionedFloat>>& MutableUnpositionedFloats() {
-    return unpositioned_floats_;
-  }
-
-  // List of floats that need to be positioned.
-  const Vector<RefPtr<NGUnpositionedFloat>>& UnpositionedFloats() const {
-    return unpositioned_floats_;
+  void SwapUnpositionedFloats(
+      Vector<RefPtr<NGUnpositionedFloat>>* unpositioned_floats) {
+    unpositioned_floats_.swap(*unpositioned_floats);
   }
 
   const WTF::Optional<NGLogicalOffset>& BfcOffset() const {
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_result.cc b/third_party/WebKit/Source/core/layout/ng/ng_layout_result.cc
index 35779bcf..1bfd897 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_result.cc
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_result.cc
@@ -11,10 +11,12 @@
     Vector<NGOutOfFlowPositionedDescendant> oof_positioned_descendants,
     Vector<RefPtr<NGUnpositionedFloat>>& unpositioned_floats,
     const WTF::Optional<NGLogicalOffset> bfc_offset,
-    const NGMarginStrut end_margin_strut)
+    const NGMarginStrut end_margin_strut,
+    NGLayoutResultStatus status)
     : physical_fragment_(std::move(physical_fragment)),
       bfc_offset_(bfc_offset),
-      end_margin_strut_(end_margin_strut) {
+      end_margin_strut_(end_margin_strut),
+      status_(status) {
   unpositioned_floats_.swap(unpositioned_floats);
   oof_positioned_descendants_.swap(oof_positioned_descendants);
 }
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_layout_result.h b/third_party/WebKit/Source/core/layout/ng/ng_layout_result.h
index 017b94f..44e9e59 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_layout_result.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_layout_result.h
@@ -26,9 +26,17 @@
 // NGFragment et al.
 class CORE_EXPORT NGLayoutResult : public RefCounted<NGLayoutResult> {
  public:
+  enum NGLayoutResultStatus {
+    kSuccess = 0,
+    kBfcOffsetResolved = 1,
+    // When adding new values, make sure the bit size of |status_| is large
+    // enough to store.
+  };
+
   RefPtr<NGPhysicalFragment> PhysicalFragment() const {
     return physical_fragment_;
   }
+
   RefPtr<NGPhysicalFragment>& MutablePhysicalFragment() {
     return physical_fragment_;
   }
@@ -50,6 +58,10 @@
     return unpositioned_floats_;
   }
 
+  NGLayoutResultStatus Status() const {
+    return static_cast<NGLayoutResultStatus>(status_);
+  }
+
   const WTF::Optional<NGLogicalOffset>& BfcOffset() const {
     return bfc_offset_;
   }
@@ -64,7 +76,8 @@
                      out_of_flow_positioned_descendants,
                  Vector<RefPtr<NGUnpositionedFloat>>& unpositioned_floats,
                  const WTF::Optional<NGLogicalOffset> bfc_offset,
-                 const NGMarginStrut end_margin_strut);
+                 const NGMarginStrut end_margin_strut,
+                 NGLayoutResultStatus status);
 
   RefPtr<NGPhysicalFragment> physical_fragment_;
   Vector<RefPtr<NGUnpositionedFloat>> unpositioned_floats_;
@@ -72,6 +85,8 @@
   Vector<NGOutOfFlowPositionedDescendant> oof_positioned_descendants_;
   const WTF::Optional<NGLogicalOffset> bfc_offset_;
   const NGMarginStrut end_margin_strut_;
+
+  unsigned status_ : 1;
 };
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp b/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp
index 6171a36d..df05ee1 100644
--- a/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp
+++ b/third_party/WebKit/Source/core/svg/animation/SMILTimeContainer.cpp
@@ -38,7 +38,6 @@
 
 namespace blink {
 
-static const double kInitialFrameDelay = 0.025;
 static const double kAnimationPolicyOnceDuration = 3.000;
 
 SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner)
@@ -176,18 +175,10 @@
   started_ = true;
 
   // If the "presentation time" is non-zero, the timeline was modified via
-  // setElapsed() before the document began.  In this case pass on
-  // 'seekToTime=true' to updateAnimations() to issue a seek.
-  SMILTime earliest_fire_time =
-      UpdateAnimations(presentation_time_, presentation_time_ ? true : false);
-  if (!CanScheduleFrame(earliest_fire_time))
-    return;
-  // If the timeline is running, and there are pending animation updates,
-  // always perform the first update after the timeline was started using
-  // the wake-up mechanism.
-  double delay_time = earliest_fire_time.Value() - presentation_time_;
-  ScheduleWakeUp(std::max(kInitialFrameDelay, delay_time),
-                 kSynchronizeAnimations);
+  // SetElapsed() before the document began. In this case pass on
+  // seek_to_time=true to issue a seek.
+  UpdateAnimationsAndScheduleFrameIfNeeded(presentation_time_,
+                                           presentation_time_ ? true : false);
 }
 
 void SMILTimeContainer::Pause() {
@@ -530,6 +521,7 @@
 }
 
 void SMILTimeContainer::AdvanceFrameForTesting() {
+  const double kInitialFrameDelay = 0.025;
   SetElapsed(Elapsed() + kInitialFrameDelay);
 }
 
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
index 57399bc..4ff50398 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.cpp
@@ -370,6 +370,26 @@
   context.DrawRect(dst_rect, flags);
 }
 
+sk_sp<PaintRecord> SVGImage::PaintRecordForContainer(
+    const KURL& url,
+    const IntSize& container_size,
+    const IntRect& draw_src_rect,
+    const IntRect& draw_dst_rect,
+    bool flip_y) {
+  if (!page_)
+    return nullptr;
+
+  PaintRecorder recorder;
+  PaintCanvas* canvas = recorder.beginRecording(draw_src_rect);
+  if (flip_y) {
+    canvas->translate(0, draw_dst_rect.Height());
+    canvas->scale(1, -1);
+  }
+  DrawForContainer(canvas, PaintFlags(), FloatSize(container_size), 1,
+                   draw_dst_rect, draw_src_rect, url);
+  return recorder.finishRecordingAsPicture();
+}
+
 sk_sp<SkImage> SVGImage::ImageForCurrentFrameForContainer(
     const KURL& url,
     const IntSize& container_size) {
diff --git a/third_party/WebKit/Source/core/svg/graphics/SVGImage.h b/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
index f37d1ef..9e393aa 100644
--- a/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
+++ b/third_party/WebKit/Source/core/svg/graphics/SVGImage.h
@@ -99,6 +99,12 @@
 
   bool HasIntrinsicDimensions() const;
 
+  sk_sp<PaintRecord> PaintRecordForContainer(const KURL&,
+                                             const IntSize& container_size,
+                                             const IntRect& draw_src_rect,
+                                             const IntRect& draw_dst_rect,
+                                             bool flip_y) override;
+
  private:
   // Accesses m_page.
   friend class SVGImageChromeClient;
diff --git a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
index c21cbd8..48fb287 100644
--- a/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
+++ b/third_party/WebKit/Source/devtools/front_end/audits2/Audits2Panel.js
@@ -112,6 +112,9 @@
    * @return {?string}
    */
   _unauditablePageMessage() {
+    if (!this._manager)
+      return null;
+
     var inspectedURL = SDK.targetManager.mainTarget().inspectedURL();
     if (/^about:/.test(inspectedURL))
       return Common.UIString('Cannot audit about:* pages. Navigate to a different page to start an audit.');
diff --git a/third_party/WebKit/Source/devtools/front_end/object_ui/RemoteObjectPreviewFormatter.js b/third_party/WebKit/Source/devtools/front_end/object_ui/RemoteObjectPreviewFormatter.js
index 632b2de7..34a4ebd 100644
--- a/third_party/WebKit/Source/devtools/front_end/object_ui/RemoteObjectPreviewFormatter.js
+++ b/third_party/WebKit/Source/devtools/front_end/object_ui/RemoteObjectPreviewFormatter.js
@@ -167,7 +167,7 @@
      */
     function appendUndefined(index) {
       var span = parentElement.createChild('span', 'object-value-undefined');
-      span.textContent = Common.UIString('undefined × %d', index - lastNonEmptyArrayIndex - 1);
+      span.textContent = Common.UIString('empty × %d', index - lastNonEmptyArrayIndex - 1);
       elementsAdded = true;
     }
   }
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/ApplicationPanelSidebar.js b/third_party/WebKit/Source/devtools/front_end/resources/ApplicationPanelSidebar.js
index 7124518d..2045085a 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/ApplicationPanelSidebar.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/ApplicationPanelSidebar.js
@@ -700,19 +700,10 @@
     this._updateChildren();
   }
 
-  _updateChildren() {
-    this.removeChildren();
-
-    /**
-     * @param {!Array.<string>} tableNames
-     * @this {Resources.DatabaseTreeElement}
-     */
-    function tableNamesCallback(tableNames) {
-      var tableNamesLength = tableNames.length;
-      for (var i = 0; i < tableNamesLength; ++i)
-        this.appendChild(new Resources.DatabaseTableTreeElement(this._sidebar, this._database, tableNames[i]));
-    }
-    this._database.getTableNames(tableNamesCallback.bind(this));
+  async _updateChildren() {
+    var tableNames = await this._database.tableNames();
+    for (var tableName of tableNames)
+      this.appendChild(new Resources.DatabaseTableTreeElement(this._sidebar, this._database, tableName));
   }
 };
 
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/DatabaseModel.js b/third_party/WebKit/Source/devtools/front_end/resources/DatabaseModel.js
index bf735c6a..1affe9a 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/DatabaseModel.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/DatabaseModel.js
@@ -81,14 +81,11 @@
   }
 
   /**
-   * @param {function(!Array.<string>)} callback
+   * @return {!Promise<!Array<string>>}
    */
-  getTableNames(callback) {
-    function sortingCallback(error, names) {
-      if (!error)
-        callback(names.sort());
-    }
-    this._model._agent.getDatabaseTableNames(this._id, sortingCallback);
+  async tableNames() {
+    var names = await this._model._agent.getDatabaseTableNames(this._id) || [];
+    return names.sort();
   }
 
   /**
@@ -96,32 +93,26 @@
    * @param {function(!Array.<string>=, !Array.<*>=)} onSuccess
    * @param {function(string)} onError
    */
-  executeSql(query, onSuccess, onError) {
-    /**
-     * @param {?Protocol.Error} error
-     * @param {!Array.<string>=} columnNames
-     * @param {!Array.<*>=} values
-     * @param {!Protocol.Database.Error=} errorObj
-     */
-    function callback(error, columnNames, values, errorObj) {
-      if (error) {
-        onError(error);
-        return;
-      }
-      if (errorObj) {
-        var message;
-        if (errorObj.message)
-          message = errorObj.message;
-        else if (errorObj.code === 2)
-          message = Common.UIString('Database no longer has expected version.');
-        else
-          message = Common.UIString('An unexpected error %s occurred.', errorObj.code);
-        onError(message);
-        return;
-      }
-      onSuccess(columnNames, values);
+  async executeSql(query, onSuccess, onError) {
+    var response = await this._model._agent.invoke_executeSQL({'databaseId': this._id, 'query': query});
+    var error = response[Protocol.Error];
+    if (error) {
+      onError(error);
+      return;
     }
-    this._model._agent.executeSQL(this._id, query, callback);
+    var sqlError = response.sqlError;
+    if (!sqlError) {
+      onSuccess(response.columnNames, response.values);
+      return;
+    }
+    var message;
+    if (sqlError.message)
+      message = sqlError.message;
+    else if (sqlError.code === 2)
+      message = Common.UIString('Database no longer has expected version.');
+    else
+      message = Common.UIString('An unexpected error %s occurred.', sqlError.code);
+    onError(message);
   }
 };
 
diff --git a/third_party/WebKit/Source/devtools/front_end/resources/DatabaseQueryView.js b/third_party/WebKit/Source/devtools/front_end/resources/DatabaseQueryView.js
index 4dbb9d46..ab5faf087 100644
--- a/third_party/WebKit/Source/devtools/front_end/resources/DatabaseQueryView.js
+++ b/third_party/WebKit/Source/devtools/front_end/resources/DatabaseQueryView.js
@@ -59,38 +59,16 @@
    * @param {boolean=} force
    * @return {!Promise<!UI.SuggestBox.Suggestions>}
    */
-  completions(expression, prefix, force) {
+  async completions(expression, prefix, force) {
     if (!prefix)
-      return Promise.resolve([]);
-    var fulfill;
-    var promise = new Promise(x => fulfill = x);
-    var results = [];
+      return [];
 
     prefix = prefix.toLowerCase();
-
-    function accumulateMatches(textArray) {
-      for (var i = 0; i < textArray.length; ++i) {
-        var text = textArray[i].toLowerCase();
-        if (text.length < prefix.length)
-          continue;
-        if (!text.startsWith(prefix))
-          continue;
-        results.push(textArray[i]);
-      }
-    }
-    function tableNamesCallback(tableNames) {
-      accumulateMatches(tableNames.map(function(name) {
-        return name + ' ';
-      }));
-      accumulateMatches([
-        'SELECT ', 'FROM ', 'WHERE ', 'LIMIT ', 'DELETE FROM ', 'CREATE ', 'DROP ', 'TABLE ', 'INDEX ', 'UPDATE ',
-        'INSERT INTO ', 'VALUES ('
-      ]);
-
-      fulfill(results.map(completion => ({text: completion})));
-    }
-    this.database.getTableNames(tableNamesCallback);
-    return promise;
+    var tableNames = await this.database.tableNames();
+    return tableNames.map(name => name + ' ')
+        .concat(Resources.DatabaseQueryView._SQL_BUILT_INS)
+        .filter(proposal => proposal.toLowerCase().startsWith(prefix))
+        .map(completion => ({text: completion}));
   }
 
   _selectStart(event) {
@@ -200,3 +178,8 @@
 Resources.DatabaseQueryView.Events = {
   SchemaUpdated: Symbol('SchemaUpdated')
 };
+
+Resources.DatabaseQueryView._SQL_BUILT_INS = [
+  'SELECT ', 'FROM ', 'WHERE ', 'LIMIT ', 'DELETE FROM ', 'CREATE ', 'DROP ', 'TABLE ', 'INDEX ', 'UPDATE ',
+  'INSERT INTO ', 'VALUES ('
+];
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
index 4013fea5..595ac76 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/JavaScriptSourceFrame.js
@@ -1568,14 +1568,17 @@
     }
   }
 
-  toggleBreakpointOnCurrentLine() {
+  /**
+   * @param {boolean} onlyDisable
+   */
+  toggleBreakpointOnCurrentLine(onlyDisable) {
     if (this._muted)
       return;
 
     var selection = this.textEditor.selection();
     if (!selection)
       return;
-    this._toggleBreakpoint(selection.startLine, false);
+    this._toggleBreakpoint(selection.startLine, onlyDisable);
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js b/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js
index a0e19b85..a648cce 100644
--- a/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js
+++ b/third_party/WebKit/Source/devtools/front_end/sources/SourcesView.js
@@ -153,7 +153,11 @@
     registerShortcut.call(
         this, UI.ShortcutsScreen.SourcesPanelShortcuts.GoToMember, this._showOutlineQuickOpen.bind(this));
     registerShortcut.call(
-        this, UI.ShortcutsScreen.SourcesPanelShortcuts.ToggleBreakpoint, this._toggleBreakpoint.bind(this));
+        this, UI.ShortcutsScreen.SourcesPanelShortcuts.ToggleBreakpoint,
+        this._toggleBreakpoint.bind(this, false /* onlyDisable */));
+    registerShortcut.call(
+        this, UI.ShortcutsScreen.SourcesPanelShortcuts.ToggleBreakpointEnabled,
+        this._toggleBreakpoint.bind(this, true /* onlyDisable */));
     registerShortcut.call(this, UI.ShortcutsScreen.SourcesPanelShortcuts.Save, this._save.bind(this));
     registerShortcut.call(this, UI.ShortcutsScreen.SourcesPanelShortcuts.SaveAll, this._saveAll.bind(this));
   }
@@ -660,16 +664,17 @@
   }
 
   /**
+   * @param {boolean} onlyDisable
    * @return {boolean}
    */
-  _toggleBreakpoint() {
+  _toggleBreakpoint(onlyDisable) {
     var sourceFrame = this.currentSourceFrame();
     if (!sourceFrame)
       return false;
 
     if (sourceFrame instanceof Sources.JavaScriptSourceFrame) {
       var javaScriptSourceFrame = /** @type {!Sources.JavaScriptSourceFrame} */ (sourceFrame);
-      javaScriptSourceFrame.toggleBreakpointOnCurrentLine();
+      javaScriptSourceFrame.toggleBreakpointOnCurrentLine(onlyDisable);
       return true;
     }
     return false;
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/ShortcutsScreen.js b/third_party/WebKit/Source/devtools/front_end/ui/ShortcutsScreen.js
index 08d5d51..8cf1d257 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/ShortcutsScreen.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/ShortcutsScreen.js
@@ -106,6 +106,8 @@
     section.addAlternateKeys(
         UI.ShortcutsScreen.SourcesPanelShortcuts.ToggleBreakpoint, Common.UIString('Toggle breakpoint'));
     section.addAlternateKeys(
+        UI.ShortcutsScreen.SourcesPanelShortcuts.ToggleBreakpointEnabled, Common.UIString('Toggle breakpoint enabled'));
+    section.addAlternateKeys(
         UI.shortcutRegistry.shortcutDescriptorsForAction('debugger.toggle-breakpoints-active'),
         Common.UIString('Toggle all breakpoints'));
 
@@ -432,6 +434,9 @@
 
   ToggleBreakpoint: [UI.KeyboardShortcut.makeDescriptor('b', UI.KeyboardShortcut.Modifiers.CtrlOrMeta)],
 
+  ToggleBreakpointEnabled: [UI.KeyboardShortcut.makeDescriptor(
+      'b', UI.KeyboardShortcut.Modifiers.CtrlOrMeta | UI.KeyboardShortcut.Modifiers.Shift)],
+
   NextCallFrame:
       [UI.KeyboardShortcut.makeDescriptor(UI.KeyboardShortcut.Keys.Period, UI.KeyboardShortcut.Modifiers.Ctrl)],
 
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 f927d21..c9e9ebe 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
+++ b/third_party/WebKit/Source/devtools/front_end/ui/UIUtils.js
@@ -1203,6 +1203,7 @@
  */
 UI.createInput = function(className, type) {
   var element = createElementWithClass('input', className || '');
+  element.spellcheck = false;
   element.classList.add('harmony-input');
   if (type)
     element.type = type;
diff --git a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
index 2890107..65a59e6 100644
--- a/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
+++ b/third_party/WebKit/Source/modules/canvas2d/BaseRenderingContext2D.cpp
@@ -1132,84 +1132,10 @@
   if (!DrawingCanvas())
     return;
 
-  RefPtr<Image> image;
-  FloatSize default_object_size(Width(), Height());
-  SourceImageStatus source_image_status = kInvalidSourceImageStatus;
-  if (!image_source->IsVideoElement()) {
-    AccelerationHint hint = GetImageBuffer()->IsAccelerated()
-                                ? kPreferAcceleration
-                                : kPreferNoAcceleration;
-    image = image_source->GetSourceImageForCanvas(&source_image_status, hint,
-                                                  kSnapshotReasonDrawImage,
-                                                  default_object_size);
-    if (source_image_status == kUndecodableSourceImageStatus)
-      exception_state.ThrowDOMException(
-          kInvalidStateError,
-          "The HTMLImageElement provided is in the 'broken' state.");
-    if (!image || !image->width() || !image->height())
-      return;
-  } else {
-    if (!static_cast<HTMLVideoElement*>(image_source)->HasAvailableVideoFrame())
-      return;
-  }
-
-  if (!std::isfinite(dx) || !std::isfinite(dy) || !std::isfinite(dw) ||
-      !std::isfinite(dh) || !std::isfinite(sx) || !std::isfinite(sy) ||
-      !std::isfinite(sw) || !std::isfinite(sh) || !dw || !dh || !sw || !sh)
-    return;
-
-  FloatRect src_rect = NormalizeRect(FloatRect(sx, sy, sw, sh));
-  FloatRect dst_rect = NormalizeRect(FloatRect(dx, dy, dw, dh));
-  FloatSize image_size = image_source->ElementSize(default_object_size);
-
-  ClipRectsToImageRect(FloatRect(FloatPoint(), image_size), &src_rect,
-                       &dst_rect);
-
-  image_source->AdjustDrawRects(&src_rect, &dst_rect);
-
-  if (src_rect.IsEmpty())
-    return;
-
-  DisableDeferralReason reason = kDisableDeferralReasonUnknown;
-  if (ShouldDisableDeferral(image_source, &reason))
-    DisableDeferral(reason);
-  else if (image->IsTextureBacked())
-    DisableDeferral(kDisableDeferralDrawImageWithTextureBackedSourceImage);
-
-  ValidateStateStack();
-
-  WillDrawImage(image_source);
-
-  ValidateStateStack();
-
-  // Heuristic for disabling acceleration based on anticipated texture upload
-  // overhead.
-  // See comments in CanvasHeuristicParameters.h for explanation.
-  ImageBuffer* buffer = GetImageBuffer();
-  if (buffer && buffer->IsAccelerated() && !image_source->IsAccelerated()) {
-    float src_area = src_rect.Width() * src_rect.Height();
-    if (src_area >
-        CanvasHeuristicParameters::kDrawImageTextureUploadHardSizeLimit) {
-      buffer->DisableAcceleration();
-    } else if (src_area > CanvasHeuristicParameters::
-                              kDrawImageTextureUploadSoftSizeLimit) {
-      SkRect bounds = dst_rect;
-      SkMatrix ctm = DrawingCanvas()->getTotalMatrix();
-      ctm.mapRect(&bounds);
-      float dst_area = dst_rect.Width() * dst_rect.Height();
-      if (src_area >
-          dst_area * CanvasHeuristicParameters::
-                         kDrawImageTextureUploadSoftSizeLimitScaleThreshold) {
-        buffer->DisableAcceleration();
-      }
-    }
-  }
-
-  ValidateStateStack();
-
   // TODO(xidachen): After collecting some data, come back and prune off
   // the ones that is not needed.
-  Optional<ScopedUsHistogramTimer> timer;
+  double start_time = WTF::MonotonicallyIncreasingTime();
+  Optional<CustomCountHistogram> timer;
   if (GetImageBuffer() && GetImageBuffer()->IsAccelerated()) {
     if (image_source->IsVideoElement()) {
       DEFINE_THREAD_SAFE_STATIC_LOCAL(
@@ -1293,6 +1219,82 @@
     }
   }
 
+  RefPtr<Image> image;
+  FloatSize default_object_size(Width(), Height());
+  SourceImageStatus source_image_status = kInvalidSourceImageStatus;
+  if (!image_source->IsVideoElement()) {
+    AccelerationHint hint = GetImageBuffer()->IsAccelerated()
+                                ? kPreferAcceleration
+                                : kPreferNoAcceleration;
+    image = image_source->GetSourceImageForCanvas(&source_image_status, hint,
+                                                  kSnapshotReasonDrawImage,
+                                                  default_object_size);
+    if (source_image_status == kUndecodableSourceImageStatus) {
+      exception_state.ThrowDOMException(
+          kInvalidStateError,
+          "The HTMLImageElement provided is in the 'broken' state.");
+    }
+    if (!image || !image->width() || !image->height())
+      return;
+  } else {
+    if (!static_cast<HTMLVideoElement*>(image_source)->HasAvailableVideoFrame())
+      return;
+  }
+
+  if (!std::isfinite(dx) || !std::isfinite(dy) || !std::isfinite(dw) ||
+      !std::isfinite(dh) || !std::isfinite(sx) || !std::isfinite(sy) ||
+      !std::isfinite(sw) || !std::isfinite(sh) || !dw || !dh || !sw || !sh)
+    return;
+
+  FloatRect src_rect = NormalizeRect(FloatRect(sx, sy, sw, sh));
+  FloatRect dst_rect = NormalizeRect(FloatRect(dx, dy, dw, dh));
+  FloatSize image_size = image_source->ElementSize(default_object_size);
+
+  ClipRectsToImageRect(FloatRect(FloatPoint(), image_size), &src_rect,
+                       &dst_rect);
+
+  image_source->AdjustDrawRects(&src_rect, &dst_rect);
+
+  if (src_rect.IsEmpty())
+    return;
+
+  DisableDeferralReason reason = kDisableDeferralReasonUnknown;
+  if (ShouldDisableDeferral(image_source, &reason))
+    DisableDeferral(reason);
+  else if (image->IsTextureBacked())
+    DisableDeferral(kDisableDeferralDrawImageWithTextureBackedSourceImage);
+
+  ValidateStateStack();
+
+  WillDrawImage(image_source);
+
+  ValidateStateStack();
+
+  // Heuristic for disabling acceleration based on anticipated texture upload
+  // overhead.
+  // See comments in CanvasHeuristicParameters.h for explanation.
+  ImageBuffer* buffer = GetImageBuffer();
+  if (buffer && buffer->IsAccelerated() && !image_source->IsAccelerated()) {
+    float src_area = src_rect.Width() * src_rect.Height();
+    if (src_area >
+        CanvasHeuristicParameters::kDrawImageTextureUploadHardSizeLimit) {
+      buffer->DisableAcceleration();
+    } else if (src_area > CanvasHeuristicParameters::
+                              kDrawImageTextureUploadSoftSizeLimit) {
+      SkRect bounds = dst_rect;
+      SkMatrix ctm = DrawingCanvas()->getTotalMatrix();
+      ctm.mapRect(&bounds);
+      float dst_area = dst_rect.Width() * dst_rect.Height();
+      if (src_area >
+          dst_area * CanvasHeuristicParameters::
+                         kDrawImageTextureUploadSoftSizeLimitScaleThreshold) {
+        buffer->DisableAcceleration();
+      }
+    }
+  }
+
+  ValidateStateStack();
+
   Draw(
       [this, &image_source, &image, &src_rect, dst_rect](
           PaintCanvas* c, const PaintFlags* flags)  // draw lambda
@@ -1328,6 +1330,9 @@
   if (OriginClean() &&
       WouldTaintOrigin(image_source, ExecutionContext::From(script_state)))
     SetOriginTainted();
+
+  timer->Count((WTF::MonotonicallyIncreasingTime() - start_time) *
+               WTF::Time::kMicrosecondsPerSecond);
 }
 
 void BaseRenderingContext2D::ClearCanvas() {
diff --git a/third_party/WebKit/Source/modules/webaudio/AudioNode.h b/third_party/WebKit/Source/modules/webaudio/AudioNode.h
index aa5ebe0..17fdffc 100644
--- a/third_party/WebKit/Source/modules/webaudio/AudioNode.h
+++ b/third_party/WebKit/Source/modules/webaudio/AudioNode.h
@@ -95,7 +95,7 @@
     kNodeTypeWaveShaper = 18,
     kNodeTypeIIRFilter = 19,
     kNodeTypeConstantSource = 20,
-    kNoteTypeAudioWorklet = 21,
+    kNodeTypeAudioWorklet = 21,
     kNodeTypeEnd = 22
   };
 
diff --git a/third_party/WebKit/Source/modules/webshare/NavigatorShare.cpp b/third_party/WebKit/Source/modules/webshare/NavigatorShare.cpp
index d72ce8c..f5d5dc1 100644
--- a/third_party/WebKit/Source/modules/webshare/NavigatorShare.cpp
+++ b/third_party/WebKit/Source/modules/webshare/NavigatorShare.cpp
@@ -107,6 +107,15 @@
                                     const ShareData& share_data) {
   Document* doc = ToDocument(ExecutionContext::From(script_state));
   DCHECK(doc);
+
+  if (!share_data.hasTitle() && !share_data.hasText() && !share_data.hasURL()) {
+    v8::Local<v8::Value> error = V8ThrowException::CreateTypeError(
+        script_state->GetIsolate(),
+        "No known share data fields supplied. If using only new fields (other "
+        "than title, text and url), you must feature-detect them first.");
+    return ScriptPromise::Reject(script_state, error);
+  }
+
   KURL full_url = doc->CompleteURL(share_data.url());
   if (!full_url.IsNull() && !full_url.IsValid()) {
     v8::Local<v8::Value> error = V8ThrowException::CreateTypeError(
@@ -116,7 +125,7 @@
 
   if (!UserGestureIndicator::ProcessingUserGesture()) {
     DOMException* error = DOMException::Create(
-        kSecurityError,
+        kNotAllowedError,
         "Must be handling a user gesture to perform a share request.");
     return ScriptPromise::RejectWithDOMException(script_state, error);
   }
diff --git a/third_party/WebKit/Source/modules/webshare/NavigatorShare.idl b/third_party/WebKit/Source/modules/webshare/NavigatorShare.idl
index 7cf20fe9..1759ca3 100644
--- a/third_party/WebKit/Source/modules/webshare/NavigatorShare.idl
+++ b/third_party/WebKit/Source/modules/webshare/NavigatorShare.idl
@@ -8,5 +8,5 @@
   RuntimeEnabled=WebShare
 ] partial interface Navigator {
   [SecureContext, CallWith=ScriptState, MeasureAs=WebShareShare]
-  Promise<void> share(ShareData data);
+  Promise<void> share(optional ShareData data);
 };
diff --git a/third_party/WebKit/Source/modules/webusb/USB.cpp b/third_party/WebKit/Source/modules/webusb/USB.cpp
index 602dced..7361f3e 100644
--- a/third_party/WebKit/Source/modules/webusb/USB.cpp
+++ b/third_party/WebKit/Source/modules/webusb/USB.cpp
@@ -16,10 +16,9 @@
 #include "modules/webusb/USBDevice.h"
 #include "modules/webusb/USBDeviceFilter.h"
 #include "modules/webusb/USBDeviceRequestOptions.h"
+#include "platform/feature_policy/FeaturePolicy.h"
 #include "platform/mojo/MojoHelper.h"
 #include "platform/wtf/Functional.h"
-#include "public/platform/InterfaceProvider.h"
-#include "public/platform/Platform.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
 
 using device::mojom::blink::UsbDeviceFilterPtr;
@@ -83,7 +82,7 @@
         script_state, DOMException::Create(kNotSupportedError));
   }
 
-  if (RuntimeEnabledFeatures::FeaturePolicyEnabled()) {
+  if (IsSupportedInFeaturePolicy(WebFeaturePolicyFeature::kUsb)) {
     if (!frame->IsFeatureEnabled(WebFeaturePolicyFeature::kUsb)) {
       return ScriptPromise::RejectWithDOMException(
           script_state,
@@ -112,7 +111,7 @@
         script_state, DOMException::Create(kNotSupportedError));
   }
 
-  if (RuntimeEnabledFeatures::FeaturePolicyEnabled()) {
+  if (IsSupportedInFeaturePolicy(WebFeaturePolicyFeature::kUsb)) {
     if (!frame->IsFeatureEnabled(WebFeaturePolicyFeature::kUsb)) {
       return ScriptPromise::RejectWithDOMException(
           script_state,
@@ -258,7 +257,7 @@
   if (!frame)
     return;
 
-  if (RuntimeEnabledFeatures::FeaturePolicyEnabled()) {
+  if (IsSupportedInFeaturePolicy(WebFeaturePolicyFeature::kUsb)) {
     if (frame->IsFeatureEnabled(WebFeaturePolicyFeature::kUsb))
       EnsureDeviceManagerConnection();
   } else if (frame->IsMainFrame()) {
diff --git a/third_party/WebKit/Source/platform/bindings/RuntimeCallStats.h b/third_party/WebKit/Source/platform/bindings/RuntimeCallStats.h
index bf5be1b..cd7603df 100644
--- a/third_party/WebKit/Source/platform/bindings/RuntimeCallStats.h
+++ b/third_party/WebKit/Source/platform/bindings/RuntimeCallStats.h
@@ -176,20 +176,28 @@
   V(AssociateObjectWithWrapper)                                         \
   V(CollectGarbage)                                                     \
   V(CreateWrapper)                                                      \
+  V(GetEventListener)                                                   \
+  V(HasInstance)                                                        \
+  V(DocumentFragmentParseHTML)                                          \
   V(PaintContents)                                                      \
   V(PerformIdleLazySweep)                                               \
   V(ProcessStyleSheet)                                                  \
   V(ToExecutionContext)                                                 \
   V(ToV8DOMWindow)                                                      \
+  V(ToV8SequenceInternal)                                               \
   V(UpdateLayerPositionsAfterLayout)                                    \
   V(UpdateLayout)                                                       \
   V(UpdateStyle)                                                        \
   V(SetReturnValueFromStringSlow)                                       \
   V(V8ExternalStringSlow)                                               \
   V(V8)                                                                 \
+  BINDINGS_METHOD(V, ElementGetBoundingClientRect)                      \
   BINDINGS_METHOD(V, EventTargetDispatchEvent)                          \
   BINDINGS_METHOD(V, HTMLElementClick)                                  \
+  BINDINGS_METHOD(V, NodeAppendChild)                                   \
+  BINDINGS_METHOD(V, NodeRemoveChild)                                   \
   BINDINGS_METHOD(V, WindowSetTimeout)                                  \
+  BINDINGS_ATTRIBUTE(V, DocumentCookie)                                 \
   BINDINGS_ATTRIBUTE(V, ElementInnerHTML)                               \
   V(TestCounter1)                                                       \
   V(TestCounter2)                                                       \
diff --git a/third_party/WebKit/Source/platform/bindings/ToV8.h b/third_party/WebKit/Source/platform/bindings/ToV8.h
index 1cfa16a..61052b9 100644
--- a/third_party/WebKit/Source/platform/bindings/ToV8.h
+++ b/third_party/WebKit/Source/platform/bindings/ToV8.h
@@ -233,6 +233,8 @@
     const Sequence& sequence,
     v8::Local<v8::Object> creation_context,
     v8::Isolate* isolate) {
+  RUNTIME_CALL_TIMER_SCOPE(isolate,
+                           RuntimeCallStats::CounterId::kToV8SequenceInternal);
   v8::Local<v8::Array> array;
   {
     v8::Context::Scope context_scope(creation_context->CreationContext());
diff --git a/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp b/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp
index cf34f7b..6ba47d5 100644
--- a/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp
+++ b/third_party/WebKit/Source/platform/bindings/V8PerIsolateData.cpp
@@ -221,6 +221,8 @@
 bool V8PerIsolateData::HasInstance(
     const WrapperTypeInfo* untrusted_wrapper_type_info,
     v8::Local<v8::Value> value) {
+  RUNTIME_CALL_TIMER_SCOPE(GetIsolate(),
+                           RuntimeCallStats::CounterId::kHasInstance);
   return HasInstance(untrusted_wrapper_type_info, value,
                      interface_template_map_for_main_world_) ||
          HasInstance(untrusted_wrapper_type_info, value,
diff --git a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp
index 3498cc3e..3872ae6c 100644
--- a/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp
+++ b/third_party/WebKit/Source/platform/feature_policy/FeaturePolicy.cpp
@@ -85,6 +85,9 @@
 }
 
 bool IsSupportedInFeaturePolicy(WebFeaturePolicyFeature feature) {
+  if (!RuntimeEnabledFeatures::FeaturePolicyEnabled())
+    return false;
+
   switch (feature) {
     // TODO(loonybear): Re-enabled fullscreen in feature policy once tests have
     // been updated.
@@ -92,6 +95,7 @@
     case WebFeaturePolicyFeature::kFullscreen:
       return false;
     case WebFeaturePolicyFeature::kPayment:
+    case WebFeaturePolicyFeature::kUsb:
       return true;
     case WebFeaturePolicyFeature::kVibrate:
       return RuntimeEnabledFeatures::FeaturePolicyExperimentalFeaturesEnabled();
diff --git a/third_party/WebKit/Source/platform/graphics/Image.h b/third_party/WebKit/Source/platform/graphics/Image.h
index d09fa73..6484f18 100644
--- a/third_party/WebKit/Source/platform/graphics/Image.h
+++ b/third_party/WebKit/Source/platform/graphics/Image.h
@@ -38,6 +38,8 @@
 #include "platform/graphics/paint/PaintCanvas.h"
 #include "platform/graphics/paint/PaintFlags.h"
 #include "platform/graphics/paint/PaintImage.h"
+#include "platform/graphics/paint/PaintRecord.h"
+#include "platform/weborigin/KURL.h"
 #include "platform/wtf/Assertions.h"
 #include "platform/wtf/Noncopyable.h"
 #include "platform/wtf/PassRefPtr.h"
@@ -199,6 +201,15 @@
                                         const FloatRect& dest,
                                         const FloatSize& image_size);
 
+  virtual sk_sp<PaintRecord> PaintRecordForContainer(
+      const KURL& url,
+      const IntSize& container_size,
+      const IntRect& draw_src_rect,
+      const IntRect& draw_dst_rect,
+      bool flip_y) {
+    return nullptr;
+  }
+
  protected:
   Image(ImageObserver* = 0, bool is_multipart = false);
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/common.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/common.py
index bef45b6e..7f69c7b 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/common.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/common.py
@@ -11,24 +11,19 @@
 from webkitpy.w3c.chromium_finder import absolute_chromium_dir
 
 
-WPT_DEST_NAME = 'wpt'
 WPT_GH_ORG = 'w3c'
 WPT_GH_REPO_NAME = 'web-platform-tests'
 WPT_GH_URL = 'https://github.com/%s/%s/' % (WPT_GH_ORG, WPT_GH_REPO_NAME)
+WPT_MIRROR_URL = 'https://chromium.googlesource.com/external/w3c/web-platform-tests.git'
 WPT_GH_SSH_URL_TEMPLATE = 'https://{}@github.com/%s/%s.git' % (WPT_GH_ORG, WPT_GH_REPO_NAME)
 WPT_REVISION_FOOTER = 'WPT-Export-Revision:'
 DEFAULT_COMMIT_HISTORY_WINDOW = 5000
 EXPORT_PR_LABEL = 'chromium-export'
 PROVISIONAL_PR_LABEL = 'do not merge yet'
 
-# TODO(qyearsley): This directory should be able to be constructed with
-# PathFinder and WPT_DEST_NAME, plus the string "external".
+# TODO(qyearsley): Avoid hard-coding third_party/WebKit/LayoutTests.
 CHROMIUM_WPT_DIR = 'third_party/WebKit/LayoutTests/external/wpt/'
 
-# Our mirrors of the official wpt repo, which we pull from.
-WPT_REPO_URL = 'https://chromium.googlesource.com/external/w3c/web-platform-tests.git'
-
-
 _log = logging.getLogger(__name__)
 
 
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py
index f35640c..489d193b 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt.py
@@ -8,7 +8,7 @@
 
 from webkitpy.common.system.executive import ScriptError
 from webkitpy.w3c.chromium_commit import ChromiumCommit
-from webkitpy.w3c.common import WPT_GH_SSH_URL_TEMPLATE, CHROMIUM_WPT_DIR
+from webkitpy.w3c.common import WPT_GH_SSH_URL_TEMPLATE, WPT_MIRROR_URL, CHROMIUM_WPT_DIR
 
 _log = logging.getLogger(__name__)
 
@@ -29,16 +29,21 @@
         self.gh_token = gh_token
 
     def fetch(self):
-        """Fetches a copy of the web-platform-tests repo into `self.path`."""
-        assert self.gh_token, 'LocalWPT.gh_token required for fetch'
+        """Fetches a copy of the web-platform-tests repo in `self.path`."""
         if self.host.filesystem.exists(self.path):
             _log.info('WPT checkout exists at %s, fetching latest', self.path)
             self.run(['git', 'fetch', 'origin'])
             self.run(['git', 'checkout', 'origin/master'])
-        else:
-            _log.info('Cloning GitHub w3c/web-platform-tests into %s', self.path)
+            return
+
+        _log.info('Cloning GitHub w3c/web-platform-tests into %s', self.path)
+        if self.gh_token:
             remote_url = WPT_GH_SSH_URL_TEMPLATE.format(self.gh_token)
-            self.host.executive.run_command(['git', 'clone', remote_url, self.path])
+        else:
+            remote_url = WPT_MIRROR_URL
+            _log.info('No credentials given, using wpt mirror URL.')
+            _log.info('It is possible for the mirror to be delayed; see https://crbug.com/698272.')
+        self.host.executive.run_command(['git', 'clone', remote_url, self.path])
 
     def run(self, command, **kwargs):
         """Runs a command in the local WPT directory."""
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py
index 3341eca..a982df0 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/local_wpt_unittest.py
@@ -12,13 +12,6 @@
 
 class LocalWPTTest(unittest.TestCase):
 
-    def test_fetch_requires_gh_token(self):
-        host = MockHost()
-        local_wpt = LocalWPT(host)
-
-        with self.assertRaises(AssertionError):
-            local_wpt.fetch()
-
     def test_fetch_when_wpt_dir_exists(self):
         host = MockHost()
         host.filesystem = MockFileSystem(files={
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
index cdceff0..05fae4c5 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer.py
@@ -19,7 +19,7 @@
 from webkitpy.common.path_finder import PathFinder
 from webkitpy.layout_tests.models.test_expectations import TestExpectations, TestExpectationParser
 from webkitpy.layout_tests.port.base import Port
-from webkitpy.w3c.common import WPT_REPO_URL, WPT_DEST_NAME, read_credentials, exportable_commits_over_last_n_commits
+from webkitpy.w3c.common import read_credentials, exportable_commits_over_last_n_commits
 from webkitpy.w3c.directory_owners_extractor import DirectoryOwnersExtractor
 from webkitpy.w3c.local_wpt import LocalWPT
 from webkitpy.w3c.test_copier import TestCopier
@@ -48,11 +48,6 @@
     def main(self, argv=None):
         options = self.parse_args(argv)
 
-        credentials = read_credentials(self.host, options.credentials_json)
-        if self.wpt_github is None:
-            self.wpt_github = WPTGitHub(
-                self.host, credentials.get('GH_USER'), credentials.get('GH_TOKEN'))
-
         self.verbose = options.verbose
         log_level = logging.DEBUG if self.verbose else logging.INFO
         logging.basicConfig(level=log_level, format='%(message)s')
@@ -60,24 +55,21 @@
         if not self.checkout_is_okay(options.allow_local_commits):
             return 1
 
+        credentials = read_credentials(self.host, options.credentials_json)
+        gh_user = credentials.get('GH_USER')
+        gh_token = credentials.get('GH_TOKEN')
+        self.wpt_github = self.wpt_github or WPTGitHub(self.host, gh_user, gh_token)
+        local_wpt = LocalWPT(self.host, gh_token=gh_token)
         self.git_cl = GitCL(self.host, auth_refresh_token_json=options.auth_refresh_token_json)
 
         _log.debug('Noting the current Chromium commit.')
         _, show_ref_output = self.run(['git', 'show-ref', 'HEAD'])
         chromium_commit = show_ref_output.split()[0]
 
-        dest_dir_name = WPT_DEST_NAME
-        repo_url = WPT_REPO_URL
-
-        # TODO(qyearsley): Simplify this to use LocalWPT.fetch when csswg-test
-        # is merged into web-platform-tests (crbug.com/706118).
-        temp_repo_path = self.finder.path_from_layout_tests(dest_dir_name)
-        _log.info('Cloning repo: %s', repo_url)
-        _log.info('Local path: %s', temp_repo_path)
-        self.run(['git', 'clone', repo_url, temp_repo_path])
+        local_wpt.fetch()
 
         if not options.ignore_exportable_commits:
-            commits = self.exportable_but_not_exported_commits(temp_repo_path)
+            commits = self.exportable_but_not_exported_commits(local_wpt)
             if commits:
                 _log.info('There were exportable but not-yet-exported commits:')
                 for commit in commits:
@@ -92,12 +84,9 @@
                     for path in commit.filtered_changed_files():
                         _log.info('  %s', path)
                 _log.info('Aborting import to prevent clobbering commits.')
-                self.clean_up_temp_repo(temp_repo_path)
                 return 0
 
-        import_commit = self.update(dest_dir_name, temp_repo_path, options.revision)
-
-        self.clean_up_temp_repo(temp_repo_path)
+        import_commit = self.update(local_wpt.path, options.revision)
 
         has_changes = self._has_changes()
         if not has_changes:
@@ -148,32 +137,11 @@
             _log.warning('Checkout has local commits; aborting. Use --allow-local-commits to allow this.')
             return False
 
-        temp_repo_path = self.finder.path_from_layout_tests(WPT_DEST_NAME)
-        if self.fs.exists(temp_repo_path):
-            _log.warning('%s exists; aborting.', temp_repo_path)
-            return False
-
         return True
 
-    def exportable_but_not_exported_commits(self, wpt_path):
-        """Checks for commits that might be overwritten by importing and lists them.
-
-        Args:
-            wpt_path: The path to a local checkout of web-platform-tests.
-
-        Returns:
-            A list of commits in the Chromium repo that are exportable
-            but not yet exported to the web-platform-tests repo.
-        """
-        assert self.host.filesystem.exists(wpt_path)
-        local_wpt = LocalWPT(self.host, path=wpt_path)
-        return exportable_commits_over_last_n_commits(
-            self.host, local_wpt, self.wpt_github)
-
-    def clean_up_temp_repo(self, temp_repo_path):
-        """Removes the temporary copy of the wpt repo that was downloaded."""
-        _log.info('Deleting temp repo directory %s.', temp_repo_path)
-        self.fs.rmtree(temp_repo_path)
+    def exportable_but_not_exported_commits(self, local_wpt):
+        """Returns a list of commits that would be clobbered by importer."""
+        return exportable_commits_over_last_n_commits(self.host, local_wpt, self.wpt_github)
 
     def _generate_manifest(self, dest_path):
         """Generates MANIFEST.json for imported tests.
@@ -193,35 +161,34 @@
         self.copyfile(manifest_path, manifest_base_path)
         self.run(['git', 'add', manifest_base_path])
 
-    def update(self, dest_dir_name, temp_repo_path, revision):
+    def update(self, local_wpt_path, revision):
         """Updates an imported repository.
 
         Args:
-            dest_dir_name: The destination directory name.
-            temp_repo_path: Path to local checkout of W3C test repo.
-            revision: A W3C test repo commit hash, or None.
+            local_wpt_path: Path to local checkout of wpt.
+            revision: A wpt commit hash to check out, or None.
 
         Returns:
             A string for the commit description "<destination>@<commitish>".
         """
         if revision is not None:
             _log.info('Checking out %s', revision)
-            self.run(['git', 'checkout', revision], cwd=temp_repo_path)
+            self.run(['git', 'checkout', revision], cwd=local_wpt_path)
 
-        self.run(['git', 'submodule', 'update', '--init', '--recursive'], cwd=temp_repo_path)
+        self.run(['git', 'submodule', 'update', '--init', '--recursive'], cwd=local_wpt_path)
 
         _log.info('Noting the revision we are importing.')
-        _, show_ref_output = self.run(['git', 'show-ref', 'origin/master'], cwd=temp_repo_path)
+        _, show_ref_output = self.run(['git', 'show-ref', 'origin/master'], cwd=local_wpt_path)
         master_commitish = show_ref_output.split()[0]
 
-        dest_path = self.finder.path_from_layout_tests('external', dest_dir_name)
+        dest_path = self.finder.path_from_layout_tests('external', 'wpt')
         self._clear_out_dest_path(dest_path)
 
         _log.info('Importing the tests.')
-        test_copier = TestCopier(self.host, temp_repo_path)
+        test_copier = TestCopier(self.host, local_wpt_path)
         test_copier.do_import()
 
-        self.run(['git', 'add', '--all', 'external/%s' % dest_dir_name])
+        self.run(['git', 'add', '--all', 'external/wpt'])
 
         self._delete_orphaned_baselines(dest_path)
 
@@ -237,7 +204,7 @@
         _log.info('Updating TestExpectations for any removed or renamed tests.')
         self.update_all_test_expectations_files(self._list_deleted_tests(), self._list_renamed_tests())
 
-        return '%s@%s' % (dest_dir_name, master_commitish)
+        return 'wpt@%s' % master_commitish
 
     def _clear_out_dest_path(self, dest_path):
         _log.info('Cleaning out tests from %s.', dest_path)
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py
index 38727022..962b05c 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/w3c/test_importer_unittest.py
@@ -19,6 +19,8 @@
 
     def test_main_abort_on_exportable_commit_if_open_pr_found(self):
         host = MockHost()
+        host.filesystem.write_text_file(
+            '/tmp/creds.json', '{"GH_USER": "x", "GH_TOKEN": "y"}')
         wpt_github = MockWPTGitHub(pull_requests=[
             PullRequest('Title', 5, 'Commit body\nChange-Id: Iba5eba11', 'open', []),
         ])
@@ -27,11 +29,10 @@
             MockChromiumCommit(host, change_id='Iba5eba11')
         ]
         importer.checkout_is_okay = lambda _: True
-        return_code = importer.main([])
+        return_code = importer.main(['--credentials-json=/tmp/creds.json'])
         self.assertEqual(return_code, 0)
         self.assertLog([
-            'INFO: Cloning repo: https://chromium.googlesource.com/external/w3c/web-platform-tests.git\n',
-            'INFO: Local path: /mock-checkout/third_party/WebKit/LayoutTests/wpt\n',
+            'INFO: Cloning GitHub w3c/web-platform-tests into /tmp/wpt\n',
             'INFO: There were exportable but not-yet-exported commits:\n',
             'INFO: Commit: https://fake-chromium-commit-viewer.org/+/14fd77e88e\n',
             'INFO: Subject: Fake commit message\n',
@@ -40,22 +41,22 @@
             'INFO:   third_party/WebKit/LayoutTests/external/wpt/one.html\n',
             'INFO:   third_party/WebKit/LayoutTests/external/wpt/two.html\n',
             'INFO: Aborting import to prevent clobbering commits.\n',
-            'INFO: Deleting temp repo directory /mock-checkout/third_party/WebKit/LayoutTests/wpt.\n',
         ])
 
     def test_main_abort_on_exportable_commit_if_no_pr_found(self):
         host = MockHost()
+        host.filesystem.write_text_file(
+            '/tmp/creds.json', '{"GH_USER": "x", "GH_TOKEN": "y"}')
         wpt_github = MockWPTGitHub(pull_requests=[])
         importer = TestImporter(host, wpt_github=wpt_github)
         importer.exportable_but_not_exported_commits = lambda _: [
             MockChromiumCommit(host, position='refs/heads/master@{#431}')
         ]
         importer.checkout_is_okay = lambda _: True
-        return_code = importer.main([])
+        return_code = importer.main(['--credentials-json=/tmp/creds.json'])
         self.assertEqual(return_code, 0)
         self.assertLog([
-            'INFO: Cloning repo: https://chromium.googlesource.com/external/w3c/web-platform-tests.git\n',
-            'INFO: Local path: /mock-checkout/third_party/WebKit/LayoutTests/wpt\n',
+            'INFO: Cloning GitHub w3c/web-platform-tests into /tmp/wpt\n',
             'INFO: There were exportable but not-yet-exported commits:\n',
             'INFO: Commit: https://fake-chromium-commit-viewer.org/+/fa2de685c0\n',
             'INFO: Subject: Fake commit message\n',
@@ -64,7 +65,6 @@
             'INFO:   third_party/WebKit/LayoutTests/external/wpt/one.html\n',
             'INFO:   third_party/WebKit/LayoutTests/external/wpt/two.html\n',
             'INFO: Aborting import to prevent clobbering commits.\n',
-            'INFO: Deleting temp repo directory /mock-checkout/third_party/WebKit/LayoutTests/wpt.\n',
         ])
 
     def test_do_auto_update_no_results(self):
diff --git a/third_party/WebKit/Tools/Scripts/wpt-export b/third_party/WebKit/Tools/Scripts/wpt-export
index 841e52d..930da13f 100755
--- a/third_party/WebKit/Tools/Scripts/wpt-export
+++ b/third_party/WebKit/Tools/Scripts/wpt-export
@@ -34,7 +34,7 @@
         help='See what would be done without actually creating or merging '
              'any pull requests.')
     parser.add_argument(
-        '--credentials-json',
+        '--credentials-json', required=True,
         help='A JSON file with an object containing zero or more of the '
              'following keys: GH_USER, GH_TOKEN, GERRIT_USER, GERRIT_TOKEN')
     args = parser.parse_args()
diff --git a/third_party/gvr-android-sdk/native_callbacks_jni.h b/third_party/gvr-android-sdk/native_callbacks_jni.h
index 96a4b59..8f9e0dac 100644
--- a/third_party/gvr-android-sdk/native_callbacks_jni.h
+++ b/third_party/gvr-android-sdk/native_callbacks_jni.h
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// This file is autogenerated by
+// This file is of the same format as file that generated by
 //     base/android/jni_generator/jni_generator.py
 // For
 //     com/google/vr/internal/controller/NativeCallbacks
diff --git a/tools/chrome_proxy/webdriver/lite_page.py b/tools/chrome_proxy/webdriver/lite_page.py
index 0528cc8..be6ecd4 100644
--- a/tools/chrome_proxy/webdriver/lite_page.py
+++ b/tools/chrome_proxy/webdriver/lite_page.py
@@ -98,6 +98,7 @@
 
   # Checks that a Lite Page is not served for the Cellular-Only option but
   # not on cellular connection.
+  @ChromeVersionEqualOrAfterM(61)
   def testLitePageNotAcceptedForCellularOnlyFlag(self):
     with TestDriver() as test_driver:
       test_driver.AddChromeArg('--enable-spdy-proxy-auth')
diff --git a/tools/chrome_proxy/webdriver/smoke.py b/tools/chrome_proxy/webdriver/smoke.py
index 2aa896b8..b27524d1 100644
--- a/tools/chrome_proxy/webdriver/smoke.py
+++ b/tools/chrome_proxy/webdriver/smoke.py
@@ -7,6 +7,7 @@
 from common import TestDriver
 from common import IntegrationTest
 from decorators import NotAndroid
+from decorators import ChromeVersionEqualOrAfterM
 
 
 class Smoke(IntegrationTest):
@@ -101,6 +102,7 @@
         self.assertEqual(200, response.status)
 
   # Verify unique page IDs are sent in the Chrome-Proxy header.
+  @ChromeVersionEqualOrAfterM(59)
   def testPageID(self):
     with TestDriver() as t:
       t.AddChromeArg('--enable-spdy-proxy-auth')
diff --git a/tools/chrome_proxy/webdriver/video.py b/tools/chrome_proxy/webdriver/video.py
index 01e2866c..4c552029 100644
--- a/tools/chrome_proxy/webdriver/video.py
+++ b/tools/chrome_proxy/webdriver/video.py
@@ -52,7 +52,7 @@
   @Slow
   def testVideoMetrics(self):
     expected = {
-      'duration': 3.124,
+      'duration': 3.128,
       'webkitDecodedFrameCount': 54.0,
       'videoWidth': 1280.0,
       'videoHeight': 720.0
@@ -81,7 +81,7 @@
           'document.querySelectorAll("video")[0].%s' % metric))
         self.assertAlmostEqual(expected[metric], actual, msg="Compressed video "
           "metric doesn't match expected! Metric=%s Expected=%f Actual=%f"
-          % (metric, expected[metric], actual), places=None, delta=0.001)
+          % (metric, expected[metric], actual), places=None, delta=0.01)
 
   # Check that the compressed video can be seeked. Use a slow network to ensure
   # the entire video isn't downloaded before we have a chance to seek.
diff --git a/tools/metrics/histograms/README.md b/tools/metrics/histograms/README.md
index 7306e9a..b0c5a5b5 100644
--- a/tools/metrics/histograms/README.md
+++ b/tools/metrics/histograms/README.md
@@ -202,6 +202,17 @@
 histogram to answer a particular question, they can learn if there was a
 histogram at some point that did so even if it isn't active now.
 
+### Histogram Suffixes
+
+It is sometimes useful to record several closely related metrics, which measure
+the same type of data, with some minor variations. It is often useful to use one
+or more <histogram_suffixes> elements to save on redundant verbosity
+in [histograms.xml](./histograms.xml). If a root `<histogram>` or a `<suffix>`
+element is used only to construct a partial name, to be completed by further
+suffixes, annotate the element with the attribute `base="true"`. This instructs
+tools not to treat the partial base name as a distinct histogram. Note that
+suffixes can be applied recursively.
+
 ## When To Use Sparse Histograms
 
 Sparse histograms are well suited for recording counts of exact sample values
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 23c96520..34cb7294 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -4060,6 +4060,18 @@
   <int value="3" label="Stream was never read at all"/>
 </enum>
 
+<enum name="CheckerImagingDecision">
+  <int value="0" label="Can decode asynchronously."/>
+  <int value="1" label="Image is animated."/>
+  <int value="2" label="Image is a video frame."/>
+  <int value="3" label="Image animation state is unknown."/>
+  <int value="4" label="Image is fetched using a multi-part response."/>
+  <int value="5" label="Image is partially loaded."/>
+  <int value="6" label="Image load state is unknown."/>
+  <int value="7" label="Image was too small to consider checkering."/>
+  <int value="8" label="Image was larger than the allowed cache limit."/>
+</enum>
+
 <enum name="ChromeChannelForHistogram">
   <int value="0" label="UNKNOWN"/>
   <int value="1" label="CANARY"/>
@@ -22324,6 +22336,7 @@
   <int value="1" label="Database open failed"/>
   <int value="2" label="Invalid schema version"/>
   <int value="3" label="Error reading schema version"/>
+  <int value="4" label="Success"/>
 </enum>
 
 <enum name="LockScreenProgress">
@@ -23211,6 +23224,7 @@
   <int value="747847237" label="PhysicalWeb:enabled"/>
   <int value="752194066" label="enable-app-window-cycling"/>
   <int value="752939691" label="disable-tab-for-desktop-share"/>
+  <int value="762700519" label="enable-checker-imaging"/>
   <int value="773919225" label="disable-office-editing-component-extension"/>
   <int value="779086132" label="enable-data-reduction-proxy-alt"/>
   <int value="782167080" label="enable-new-qp-input-view"/>
@@ -23370,6 +23384,7 @@
   <int value="1280614081" label="show-overdraw-feedback"/>
   <int value="1283956865" label="force-tablet-mode"/>
   <int value="1283960113" label="disable-fixed-position-compositing"/>
+  <int value="1284910808" label="disable-checker-imaging"/>
   <int value="1291257442" label="TabsInCBD:disabled"/>
   <int value="1291966558" label="ScrollAnchoring:disabled"/>
   <int value="1294131571" label="disable-winrt-midi-api"/>
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index d50fc40..deb3871 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -36,7 +36,7 @@
 
   <histogram name="FileLoadLatency"/>
 
-  <histogram_suffixes name="SuperHttpExperiment">
+  <histogram_suffixes name="SuperHttpExperiment" separator=".">
     <suffix name="SuperHttpEnabled"/>
     <suffix name="SuperHttpDisabled"/>
     <affected-histogram name="FileLoadLatency"/>
@@ -45,14 +45,14 @@
 The complete list of histograms will be:
 
   FileLoadLatency
-  FileLoadLatency_SuperHttpEnabled
-  FileLoadLatency_SuperHttpDisabled
+  FileLoadLatency.SuperHttpEnabled
+  FileLoadLatency.SuperHttpDisabled
 
 histogram_suffixes can also be used to insert affix in the middle. Example:
 
   <histogram name="Prerender.Events"/>
 
-  <histogram_suffixes name="SuperHttpExperiment" ordering="prefix">
+  <histogram_suffixes name="HoverStatsTypes" separator="_" ordering="prefix">
     <suffix name="HoverStats50"/>
     <affected-histogram name="Prerender.Events"/>
   </histogram_suffixes>
@@ -68,6 +68,11 @@
 how many dots the suffix should be inserted (default=1). The affected-histogram
 name has to have at least N dots in it.
 
+If a <histogram> or a <suffix> element is only provided so that its name can be
+extended by <histogram_suffixes>, the element should be annotated with the
+attribute base="true". This instructs tools not to treat the base name as a
+distinct histogram.
+
 Googlers: There are also a small number of private internal histograms found at
 http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
 -->
@@ -621,6 +626,26 @@
   </summary>
 </histogram>
 
+<histogram name="Android.ChildProcessLauncher.OnServiceConnectedTime"
+    units="ms">
+  <owner>boliu@chromium.org</owner>
+  <summary>
+    Measure time from bindService call to onServiceConnected. This is part of
+    launching child services on Android that's under Android's control. Recorded
+    in the first onServiceConnected of a connection.
+  </summary>
+</histogram>
+
+<histogram name="Android.ChildProcessLauncher.OnServiceConnectedTimedOut"
+    enum="BooleanTimedOut">
+  <owner>boliu@chromium.org</owner>
+  <summary>
+    Boolean histogram that records whether bindServiced timed out. Timeout is
+    recorded in a delayed task, and success is recorded in onServiceConnected
+    callback.
+  </summary>
+</histogram>
+
 <histogram name="Android.ChromeHome.DurationOpen" units="ms">
   <owner>mdjones@chromium.org</owner>
   <owner>twellington@chromium.org</owner>
@@ -1760,6 +1785,15 @@
   </summary>
 </histogram>
 
+<histogram name="Arc.FirstAppLaunchRequest.TimeDelta" units="ms">
+  <owner>yusukes@google.com</owner>
+  <owner>khmel@google.com</owner>
+  <summary>
+    Elapsed time from the when UI is shown after login to when the user
+    activates first ARC app.
+  </summary>
+</histogram>
+
 <histogram name="Arc.FirstComplianceReportTime.SinceSignIn" units="ms">
   <owner>alexchau@google.com</owner>
   <owner>emaxx@google.com</owner>
@@ -8754,6 +8788,19 @@
   </summary>
 </histogram>
 
+<histogram name="Compositing.Renderer.CheckerImagingDecision"
+    enum="CheckerImagingDecision">
+  <owner>khushalsagar@chromium.org</owner>
+  <summary>
+    The outcome for whether an image could be sucessfully deferred for
+    asynchronous decode in the renderer compositor. If not, the reason for using
+    a synchronous decode. An image which is decoded asynchronously will be
+    checkerboarded on the rasterized tiles until the decode is finished, as
+    opposed to synchronous decodes where the tile rasterization is blocked on
+    the image decode completing.
+  </summary>
+</histogram>
+
 <histogram
     name="Compositing.Renderer.DisplayListRecordingSource.UpdateInvalidatedAreaPerMs"
     units="pixels/ms">
@@ -27802,14 +27849,14 @@
   <summary>Records events related to local discovery notifications.</summary>
 </histogram>
 
-<histogram name="LocalNetworkRequests.PrivatePage" units="requests">
+<histogram base="true" name="LocalNetworkRequests.PrivatePage" units="requests">
   <owner>uthakore@chromium.org</owner>
   <summary>
     Number of requests made by a private page to resources besides itself.
   </summary>
 </histogram>
 
-<histogram name="LocalNetworkRequests.PublicPage" units="requests">
+<histogram base="true" name="LocalNetworkRequests.PublicPage" units="requests">
   <owner>uthakore@chromium.org</owner>
   <summary>
     Number of requests made by a public page to resources with reserved IP
@@ -27980,6 +28027,16 @@
   </summary>
 </histogram>
 
+<histogram base="true" name="LocalStorageContext.OpenResultAfter"
+    enum="LocalStorageOpenError">
+<!-- Name completed by histogram_suffixes name="LocalStorageContextOpenReasons" -->
+
+  <owner>mek@chromium.org</owner>
+  <summary>
+    The result of opening the LevelDB database that backs LocalStorage.
+  </summary>
+</histogram>
+
 <histogram name="LocalStorageContext.ReadVersionError" enum="LevelDBStatus">
   <owner>mek@chromium.org</owner>
   <summary>
@@ -37730,6 +37787,9 @@
 </histogram>
 
 <histogram name="Net.HttpContentLength" units="bytes">
+  <obsolete>
+    Replaced by Net.HttpContentLengthV2
+  </obsolete>
   <owner>bengr@chromium.org</owner>
   <summary>
     Size of the response body. This is the actual number of bytes received,
@@ -37783,6 +37843,17 @@
   </summary>
 </histogram>
 
+<histogram name="Net.HttpContentLengthV2" units="bytes">
+  <owner>bengr@chromium.org</owner>
+  <summary>
+    Size of the response body. This is the actual number of bytes received,
+    which usually agrees with but is not necessarily the same as the size
+    specified by the Content-Length header. Replaces Net.HttpContentLength,
+    recording non-DRP Http traffic as &quot;Http.Direct&quot; instead of
+    &quot;Http.Other&quot;.
+  </summary>
+</histogram>
+
 <histogram name="Net.HttpContentLengthWithValidOCL" units="bytes">
   <owner>bengr@chromium.org</owner>
   <summary>
@@ -37861,6 +37932,10 @@
 </histogram>
 
 <histogram name="Net.HttpOriginalContentLength" units="bytes">
+  <obsolete>
+    Should be removed once consumers have been updated to use
+    Net.HttpOriginalContentLengthV2
+  </obsolete>
   <owner>bengr@chromium.org</owner>
   <summary>
     Size specified in the X-Original-Content-Length header. If this header is
@@ -37868,6 +37943,19 @@
   </summary>
 </histogram>
 
+<histogram name="Net.HttpOriginalContentLengthV2" units="bytes">
+  <owner>bengr@chromium.org</owner>
+  <summary>
+    Net.HttpOriginalContentLength with non-data reduction proxy traffic properly
+    labeled with the &quot;Direct&quot; suffix.
+
+    Size specified in the X-Original-Content-Length header. If this header is
+    not present in the response, the size of the response body is used. Replaces
+    Net.HttpOriginalContentLength, breaking down traffic by Direct, ViaDRP,
+    Bypassed, and Other.
+  </summary>
+</histogram>
+
 <histogram name="Net.HttpOriginalContentLengthWithValidOCL" units="bytes">
   <owner>bengr@chromium.org</owner>
   <summary>
@@ -73466,8 +73554,8 @@
     enum="SoftwareReporterCleanerDownloadStatus">
   <owner>ftirelo@chromium.org</owner>
   <summary>
-    An indication if an attempt to download the Chrome Cleanup Tool succeeded
-    or the reason why it failed.
+    An indication if an attempt to download the Chrome Cleanup Tool succeeded or
+    the reason why it failed.
   </summary>
 </histogram>
 
@@ -73491,11 +73579,11 @@
 <histogram name="SoftwareReporter.Cleaner.RebootResponse" enum="Boolean">
   <owner>ftirelo@chromium.org</owner>
   <summary>
-    Indicates that the user accepted to initiate a reboot to complete a run
-    of the Chrome Cleanup Tool. This is logged the user starts a reboot from
-    the cleanup card in the Settings page. We can't track when the reboot is
-    not initiated, because it can happen at any moment in the future (there is
-    no prompt blocking the user).
+    Indicates that the user accepted to initiate a reboot to complete a run of
+    the Chrome Cleanup Tool. This is logged the user starts a reboot from the
+    cleanup card in the Settings page. We can't track when the reboot is not
+    initiated, because it can happen at any moment in the future (there is no
+    prompt blocking the user).
   </summary>
 </histogram>
 
@@ -73513,8 +73601,8 @@
   <owner>ftirelo@chromium.org</owner>
   <summary>
     Whether the user accepted to upload logs from Chrome Cleanup Tool. This is
-    logged when the user accepts the Chrome prompt to start a cleanup either from
-    the prompt dialog or from the cleanup card in the Settings page.
+    logged when the user accepts the Chrome prompt to start a cleanup either
+    from the prompt dialog or from the cleanup card in the Settings page.
   </summary>
 </histogram>
 
@@ -73529,8 +73617,8 @@
     enum="SoftwareReporterCleanupStarted">
   <owner>ftirelo@chromium.org</owner>
   <summary>
-    Indicates where the user started a cleanup from (e.g. from the prompt
-    dialog or the settings page).
+    Indicates where the user started a cleanup from (e.g. from the prompt dialog
+    or the settings page).
   </summary>
 </histogram>
 
@@ -73559,9 +73647,9 @@
     from Chrome. Success is logged when it's disconnected and no longer needed
     (the user already responded to the prompt in Chrome or the cleaner process
     terminated normally); failures are logged when the IPC is disconnected, but
-    communication between Chrome and the cleaner process is still required
-    (e.g. while Chrome is waiting for scanning results or when the cleaner is
-    waiting for the user's response from Chrome).
+    communication between Chrome and the cleaner process is still required (e.g.
+    while Chrome is waiting for scanning results or when the cleaner is waiting
+    for the user's response from Chrome).
   </summary>
 </histogram>
 
@@ -73629,8 +73717,8 @@
     enum="SoftwareReporterNoPromptReason">
   <owner>ftirelo@chromium.org</owner>
   <summary>
-    The reason why the user has not been prompted to run the Chrome Cleanup
-    Tool (e.g. no unwanted software found, user recently prompted).
+    The reason why the user has not been prompted to run the Chrome Cleanup Tool
+    (e.g. no unwanted software found, user recently prompted).
   </summary>
 </histogram>
 
@@ -73653,8 +73741,8 @@
     enum="SoftwareReporterPromptDialogResponse">
   <owner>ftirelo@chromium.org</owner>
   <summary>
-    The user response on the modal Chrome Cleanup Tool prompt dialog
-    (e.g. accepted, cancelled).
+    The user response on the modal Chrome Cleanup Tool prompt dialog (e.g.
+    accepted, cancelled).
   </summary>
 </histogram>
 
@@ -73706,8 +73794,8 @@
 <histogram name="SoftwareReporter.TaggedProfileForResetting" enum="Boolean">
   <owner>ftirelo@chromium.org</owner>
   <summary>
-    Registers when a profile is tagged for settings reset before a run of
-    the Chrome Cleanup Tool.
+    Registers when a profile is tagged for settings reset before a run of the
+    Chrome Cleanup Tool.
   </summary>
 </histogram>
 
@@ -91743,34 +91831,36 @@
 </histogram_suffixes>
 
 <histogram_suffixes name="LocalNetReqsLocalhostResources" separator=".">
-  <suffix name="Localhost.DbRequests"
+  <suffix base="true" name="Localhost.DbRequests"
       label="Requests made to localhost on a database server port."/>
-  <suffix name="Localhost.DevRequests"
+  <suffix base="true" name="Localhost.DevRequests"
       label="Requests made to localhost on a development server port."/>
-  <suffix name="Localhost.OtherRequests"
+  <suffix base="true" name="Localhost.OtherRequests"
       label="Requests made to localhost on any port not otherwise monitored
              by the other local network request metrics."/>
-  <suffix name="Localhost.PrinterRequests"
+  <suffix base="true" name="Localhost.PrinterRequests"
       label="Requests made to localhost on a printer server port."/>
-  <suffix name="Localhost.WebRequests"
+  <suffix base="true" name="Localhost.WebRequests"
       label="Requests made to localhost on a web server port."/>
   <affected-histogram name="LocalNetworkRequests.PrivatePage"/>
   <affected-histogram name="LocalNetworkRequests.PublicPage"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="LocalNetReqsPrivatePage" separator=".">
-  <suffix name="DifferentSubnetRequests"
+  <suffix base="true" name="DifferentSubnetRequests"
       label="Requests made to local resources on a different subnet."/>
-  <suffix name="PublicRequests" label="Requests made to public resources."/>
-  <suffix name="SameSubnetRequests"
+  <suffix base="true" name="PublicRequests"
+      label="Requests made to public resources."/>
+  <suffix base="true" name="SameSubnetRequests"
       label="Requests made to local resources on the same reserved IP space
              as the page."/>
   <affected-histogram name="LocalNetworkRequests.PrivatePage"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="LocalNetReqsPublicPage" separator=".">
-  <suffix name="PrivateRequests" label="Requests made to private resources."/>
-  <suffix name="RouterRequests"
+  <suffix base="true" name="PrivateRequests"
+      label="Requests made to private resources."/>
+  <suffix base="true" name="RouterRequests"
       label="Requests made to resources likely to be routers."/>
   <affected-histogram name="LocalNetworkRequests.PublicPage"/>
 </histogram_suffixes>
@@ -91821,6 +91911,15 @@
   <affected-histogram name="LocalStorageContext.CachePurgedInKB"/>
 </histogram_suffixes>
 
+<histogram_suffixes name="LocalStorageContextOpenReasons" separator="">
+  <suffix name="CommitErrors" label="After too many commit errors."/>
+  <suffix name="InvalidVersion" label="After an invalid version was read."/>
+  <suffix name="OpenFailed" label="After opening the DB failed."/>
+  <suffix name="ReadVersionError"
+      label="After reading the schema version failed."/>
+  <affected-histogram name="LocalStorageContext.OpenResultAfter"/>
+</histogram_suffixes>
+
 <histogram_suffixes name="LocalStorageSizes" separator="">
   <suffix name="Under100KB" label="DB size under 100KB"/>
   <suffix name="100KBTo1MB" label="DB size between 100KB and 1MB"/>
@@ -92325,6 +92424,35 @@
   <affected-histogram name="ServiceWorker.NavigationPreload.ConcurrentTime"/>
 </histogram_suffixes>
 
+<histogram_suffixes name="NavigationType" separator=".">
+  <suffix name="NewPageInPageOriginMismatch"
+      label="in-document new page navigation with a non-matching origin"/>
+  <suffix name="NewPageInPage"
+      label="in-document new page navigation"/>
+  <suffix name="NewPagePendingEntryMatches"
+      label="new page navigation which found a pending entry"/>
+  <suffix name="NewPageNoMatchingEntry"
+      label="new page navigation with no matching entry"/>
+  <suffix name="ExistingPageSameDocumentIntendedAsNew"
+      label="in-document existing page navigation which is intended as new"/>
+  <suffix name="ExistingPageDifferentDocumentIntendedAsNew"
+      label="existing page navigation which is intended as new"/>
+  <suffix name="ExistingPageSameDocumentRestoredBrowserInitiated"
+      label="in-document existing page browser-initiated navigation which is restored"/>
+  <suffix name="ExistingPageSameDocumentBrowserInitiated"
+      label="in-document existing page browser-initiated navigation"/>
+  <suffix name="ExistingPageRestoredBrowserInitiated"
+      label="existing page browser-initiated navigation which is restored"/>
+  <suffix name="ExistingPageBrowserInitiated"
+      label="existing page browser-initiated navigation"/>
+  <suffix name="ExistingPageSameDocumentRendererInitiated"
+      label="in-document existing page renderer-initiated navigation"/>
+  <suffix name="ExistingPageDifferentDocumentRendererInitiated"
+      label="existing page renderer-initiated navigation"/>
+  <suffix name="NewSubFrame" label="new subframe navigation"/>
+  <affected-histogram name="Navigation.SecureSchemeHasSSLStatus"/>
+</histogram_suffixes>
+
 <histogram_suffixes name="Net.BidirectionalStreamExperiment" separator=".">
   <owner>xunjieli@chromium.org</owner>
   <suffix name="QUIC" label="Bidirectional streams that use QUIC protocol"/>
@@ -93615,7 +93743,9 @@
   <suffix name="Https"/>
   <suffix name="Video"/>
   <affected-histogram name="Net.HttpContentLength"/>
+  <affected-histogram name="Net.HttpContentLengthV2"/>
   <affected-histogram name="Net.HttpOriginalContentLength"/>
+  <affected-histogram name="Net.HttpOriginalContentLengthV2"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="NetHttpContentLengthType2" separator=".">
@@ -93631,8 +93761,12 @@
       label="Bytes of traffic that passed through the Data Reduction Proxy"/>
   <affected-histogram name="Net.HttpContentLength.Http"/>
   <affected-histogram name="Net.HttpContentLength.Https"/>
+  <affected-histogram name="Net.HttpContentLengthV2.Http"/>
+  <affected-histogram name="Net.HttpContentLengthV2.Https"/>
   <affected-histogram name="Net.HttpOriginalContentLength.Http"/>
   <affected-histogram name="Net.HttpOriginalContentLength.Https"/>
+  <affected-histogram name="Net.HttpOriginalContentLengthV2.Http"/>
+  <affected-histogram name="Net.HttpOriginalContentLengthV2.Https"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="NetHttpContentLengthType3" separator=".">
@@ -93645,6 +93779,30 @@
   <affected-histogram name="Net.HttpContentLength.Https.Direct"/>
   <affected-histogram name="Net.HttpContentLength.Https.Other"/>
   <affected-histogram name="Net.HttpContentLength.Https.ViaDRP"/>
+  <affected-histogram name="Net.HttpContentLengthV2.Http.BypassedDRP"/>
+  <affected-histogram name="Net.HttpContentLengthV2.Http.Direct"/>
+  <affected-histogram name="Net.HttpContentLengthV2.Http.Other"/>
+  <affected-histogram name="Net.HttpContentLengthV2.Http.ViaDRP"/>
+  <affected-histogram name="Net.HttpContentLengthV2.Https.BypassedDRP"/>
+  <affected-histogram name="Net.HttpContentLengthV2.Https.Direct"/>
+  <affected-histogram name="Net.HttpContentLengthV2.Https.Other"/>
+  <affected-histogram name="Net.HttpContentLengthV2.Https.ViaDRP"/>
+  <affected-histogram name="Net.HttpOriginalContentLength.Http.BypassedDRP"/>
+  <affected-histogram name="Net.HttpOriginalContentLength.Http.Direct"/>
+  <affected-histogram name="Net.HttpOriginalContentLength.Http.Other"/>
+  <affected-histogram name="Net.HttpOriginalContentLength.Http.ViaDRP"/>
+  <affected-histogram name="Net.HttpOriginalContentLength.Https.BypassedDRP"/>
+  <affected-histogram name="Net.HttpOriginalContentLength.Https.Direct"/>
+  <affected-histogram name="Net.HttpOriginalContentLength.Https.Other"/>
+  <affected-histogram name="Net.HttpOriginalContentLength.Https.ViaDRP"/>
+  <affected-histogram name="Net.HttpOriginalContentLengthV2.Http.BypassedDRP"/>
+  <affected-histogram name="Net.HttpOriginalContentLengthV2.Http.Direct"/>
+  <affected-histogram name="Net.HttpOriginalContentLengthV2.Http.Other"/>
+  <affected-histogram name="Net.HttpOriginalContentLengthV2.Http.ViaDRP"/>
+  <affected-histogram name="Net.HttpOriginalContentLengthV2.Https.BypassedDRP"/>
+  <affected-histogram name="Net.HttpOriginalContentLengthV2.Https.Direct"/>
+  <affected-histogram name="Net.HttpOriginalContentLengthV2.Https.Other"/>
+  <affected-histogram name="Net.HttpOriginalContentLengthV2.Https.ViaDRP"/>
 </histogram_suffixes>
 
 <histogram_suffixes name="NetHttpProxyConnectLatencySecure" separator=".">
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index d9cb199..3994165 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -489,6 +489,55 @@
   <metric name="AudioVideo.SRC"/>
 </event>
 
+<event name="Memory.Experimental">
+  <owner>erikchen@chromium.org</owner>
+  <summary>
+    Metrics associated with memory consumption, in MB.
+  </summary>
+  <metric name="BlinkGC">
+    <summary>
+      Measure of memory consumed by Oilpan.
+    </summary>
+  </metric>
+  <metric name="CommandBuffer">
+    <summary>
+      Measure of memory consumed by GL command buffer.
+    </summary>
+  </metric>
+  <metric name="Malloc">
+    <summary>
+      Measure of memory allocated by malloc.
+    </summary>
+  </metric>
+  <metric name="PartitionAlloc">
+    <summary>
+      Measure of memory allocated by PartitionAlloc.
+    </summary>
+  </metric>
+  <metric name="PrivateMemoryFootprint">
+    <summary>
+      Measure of total memory consumed by process.
+    </summary>
+  </metric>
+  <metric name="ProcessType">
+    <summary>
+      Type of process (e.g. browser, renderer, GPU --- see
+      services/resource_coordinator/public/interfaces/memory_instrumentation/memory_instrumentation.mojom)
+      of associated metrics.
+    </summary>
+  </metric>
+  <metric name="Resident">
+    <summary>
+      Size of process' working set.
+    </summary>
+  </metric>
+  <metric name="V8">
+    <summary>
+      Measure of memory consumed by V8.
+    </summary>
+  </metric>
+</event>
+
 <event name="PageDomainInfo">
   <owner>uthakore@chromium.org</owner>
   <summary>
diff --git a/tools/perf/page_sets/OWNERS b/tools/perf/page_sets/OWNERS
new file mode 100644
index 0000000..b313151
--- /dev/null
+++ b/tools/perf/page_sets/OWNERS
@@ -0,0 +1,2 @@
+per-file update_webrtc_cases=ehmaldonado@chromium.org
+per-file update_webrtc_cases=jansson@chromium.org
diff --git a/tools/perf/page_sets/webrtc_cases/OWNERS b/tools/perf/page_sets/webrtc_cases/OWNERS
new file mode 100644
index 0000000..49dd725
--- /dev/null
+++ b/tools/perf/page_sets/webrtc_cases/OWNERS
@@ -0,0 +1,2 @@
+ehmaldonado@chromium.org
+jansson@chromium.org
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn
index 22a9c49..b088686 100644
--- a/ui/android/BUILD.gn
+++ b/ui/android/BUILD.gn
@@ -62,6 +62,7 @@
     "//cc",
     "//cc/surfaces",
     "//cc/surfaces:surface_id",
+    "//components/viz/service",
     "//skia",
     "//ui/base",
     "//ui/display",
diff --git a/ui/android/DEPS b/ui/android/DEPS
index 5174f43..7f7f43f 100644
--- a/ui/android/DEPS
+++ b/ui/android/DEPS
@@ -8,6 +8,7 @@
   "+cc/test/test_task_graph_runner.h",
   "+cc/trees/layer_tree_host.h",
   "+components/viz/common",
+  "+components/viz/service/frame_sinks",
   "+jni",
   "+skia/ext",
   "+third_party/skia",
diff --git a/ui/android/delegated_frame_host_android.cc b/ui/android/delegated_frame_host_android.cc
index 72fc026b..7b5b50b 100644
--- a/ui/android/delegated_frame_host_android.cc
+++ b/ui/android/delegated_frame_host_android.cc
@@ -199,7 +199,7 @@
   constexpr bool handles_frame_sink_id_invalidation = false;
   constexpr bool needs_sync_points = true;
   support_.reset();
-  support_ = cc::CompositorFrameSinkSupport::Create(
+  support_ = viz::CompositorFrameSinkSupport::Create(
       this, frame_sink_manager_, frame_sink_id_, is_root,
       handles_frame_sink_id_invalidation, needs_sync_points);
 }
diff --git a/ui/android/delegated_frame_host_android.h b/ui/android/delegated_frame_host_android.h
index 18a0201c..3f9544c5 100644
--- a/ui/android/delegated_frame_host_android.h
+++ b/ui/android/delegated_frame_host_android.h
@@ -9,9 +9,9 @@
 #include "base/memory/ref_counted.h"
 #include "cc/output/copy_output_request.h"
 #include "cc/resources/returned_resource.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
 #include "cc/surfaces/surface_info.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h"
 #include "ui/android/ui_android_export.h"
 
 namespace cc {
@@ -28,7 +28,7 @@
 class WindowAndroidCompositor;
 
 class UI_ANDROID_EXPORT DelegatedFrameHostAndroid
-    : public cc::CompositorFrameSinkSupportClient,
+    : public viz::CompositorFrameSinkSupportClient,
       public cc::ExternalBeginFrameSourceClient {
  public:
   class Client {
@@ -73,7 +73,7 @@
   viz::SurfaceId SurfaceId() const;
 
  private:
-  // cc::CompositorFrameSinkSupportClient implementation.
+  // viz::CompositorFrameSinkSupportClient implementation.
   void DidReceiveCompositorFrameAck(
       const std::vector<cc::ReturnedResource>& resources) override;
   void OnBeginFrame(const cc::BeginFrameArgs& args) override;
@@ -95,7 +95,7 @@
   WindowAndroidCompositor* registered_parent_compositor_ = nullptr;
   Client* client_;
 
-  std::unique_ptr<cc::CompositorFrameSinkSupport> support_;
+  std::unique_ptr<viz::CompositorFrameSinkSupport> support_;
   cc::ExternalBeginFrameSource begin_frame_source_;
 
   cc::SurfaceInfo surface_info_;
diff --git a/ui/android/java/src/org/chromium/ui/DropdownPopupWindow.java b/ui/android/java/src/org/chromium/ui/DropdownPopupWindow.java
index 7286630..621db90e 100644
--- a/ui/android/java/src/org/chromium/ui/DropdownPopupWindow.java
+++ b/ui/android/java/src/org/chromium/ui/DropdownPopupWindow.java
@@ -8,11 +8,9 @@
 import android.graphics.Rect;
 import android.util.Log;
 import android.view.View;
-import android.view.View.MeasureSpec;
 import android.view.View.OnLayoutChangeListener;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
-import android.widget.LinearLayout;
 import android.widget.ListAdapter;
 import android.widget.ListPopupWindow;
 import android.widget.PopupWindow;
@@ -93,8 +91,9 @@
         // An ugly hack to keep the popup from expanding on top of the keyboard.
         setInputMethodMode(INPUT_METHOD_NEEDED);
 
-        int contentWidth = measureContentWidth();
-        float anchorWidth = mAnchorView.getLayoutParams().width;
+        assert mAdapter != null : "Set the adapter before showing the popup.";
+        final int contentWidth = UiUtils.computeMaxWidthOfListAdapterItems(mAdapter);
+        final float anchorWidth = mAnchorView.getLayoutParams().width;
         assert anchorWidth > 0;
         Rect padding = new Rect();
         getBackground().getPadding(padding);
@@ -171,21 +170,6 @@
      */
     private int measureContentWidth() {
         assert mAdapter != null : "Set the adapter before showing the popup.";
-        int maxWidth = 0;
-        View[] itemViews = new View[mAdapter.getViewTypeCount()];
-        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
-        for (int i = 0; i < mAdapter.getCount(); i++) {
-            int type = mAdapter.getItemViewType(i);
-            itemViews[type] = mAdapter.getView(i, itemViews[type], null);
-            View itemView = itemViews[type];
-            LinearLayout.LayoutParams params =
-                    new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
-                            LinearLayout.LayoutParams.WRAP_CONTENT);
-            itemView.setLayoutParams(params);
-            itemView.measure(widthMeasureSpec, heightMeasureSpec);
-            maxWidth = Math.max(maxWidth, itemView.getMeasuredWidth());
-        }
-        return maxWidth;
+        return UiUtils.computeMaxWidthOfListAdapterItems(mAdapter);
     }
 }
diff --git a/ui/android/java/src/org/chromium/ui/UiUtils.java b/ui/android/java/src/org/chromium/ui/UiUtils.java
index 3a55ab9..59cfb82 100644
--- a/ui/android/java/src/org/chromium/ui/UiUtils.java
+++ b/ui/android/java/src/org/chromium/ui/UiUtils.java
@@ -17,10 +17,13 @@
 import android.util.Log;
 import android.view.SurfaceView;
 import android.view.View;
+import android.view.View.MeasureSpec;
 import android.view.ViewGroup;
 import android.view.inputmethod.InputMethodInfo;
 import android.view.inputmethod.InputMethodManager;
 import android.view.inputmethod.InputMethodSubtype;
+import android.widget.LinearLayout;
+import android.widget.ListAdapter;
 
 import org.chromium.base.ApiCompatibilityUtils;
 
@@ -411,4 +414,43 @@
             return Typeface.create("sans-serif", Typeface.BOLD);
         }
     }
+
+    /**
+     * Iterates through all items in the specified ListAdapter (including header and footer views)
+     * and returns the width of the widest item (when laid out with height and width set to
+     * WRAP_CONTENT).
+     *
+     * WARNING: do not call this on a ListAdapter with more than a handful of items, the performance
+     * will be terrible since it measures every single item.
+     *
+     * @param adapter The ListAdapter whose widest item's width will be returned.
+     * @return The measured width (in pixels) of the widest item in the passed-in ListAdapter.
+     */
+    public static int computeMaxWidthOfListAdapterItems(ListAdapter adapter) {
+        final int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+        final int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
+                LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+
+        int maxWidth = 0;
+        View[] itemViews = new View[adapter.getViewTypeCount()];
+        for (int i = 0; i < adapter.getCount(); ++i) {
+            View itemView;
+            int type = adapter.getItemViewType(i);
+            if (type < 0) {
+                // Type is negative for header/footer views, or views the adapter does not want
+                // recycled.
+                itemView = adapter.getView(i, null, null);
+            } else {
+                itemViews[type] = adapter.getView(i, itemViews[type], null);
+                itemView = itemViews[type];
+            }
+
+            itemView.setLayoutParams(params);
+            itemView.measure(widthMeasureSpec, heightMeasureSpec);
+            maxWidth = Math.max(maxWidth, itemView.getMeasuredWidth());
+        }
+
+        return maxWidth;
+    }
 }
diff --git a/ui/app_list/views/app_list_folder_view.cc b/ui/app_list/views/app_list_folder_view.cc
index 8c2f2c1..4b7f185 100644
--- a/ui/app_list/views/app_list_folder_view.cc
+++ b/ui/app_list/views/app_list_folder_view.cc
@@ -54,7 +54,7 @@
   AddChildView(folder_header_view_);
   view_model_->Add(folder_header_view_, kIndexFolderHeader);
 
-  items_grid_view_ = new AppsGridView(app_list_main_view_);
+  items_grid_view_ = new AppsGridView(app_list_main_view_->contents_view());
   items_grid_view_->set_folder_delegate(this);
   items_grid_view_->SetLayout(
       container_view->apps_grid_view()->cols(),
diff --git a/ui/app_list/views/app_list_main_view.h b/ui/app_list/views/app_list_main_view.h
index 7d06cab3..f345a60 100644
--- a/ui/app_list/views/app_list_main_view.h
+++ b/ui/app_list/views/app_list_main_view.h
@@ -75,6 +75,10 @@
   void OnCustomLauncherPageEnabledStateChanged(bool enabled) override;
   void OnSearchEngineIsGoogleChanged(bool is_google) override;
 
+  // Overridden from AppsGridViewDelegate:
+  void ActivateApp(AppListItem* item, int event_flags) override;
+  void CancelDragInActiveFolder() override;
+
  private:
   // Adds the ContentsView.
   void AddContentsViews();
@@ -82,10 +86,6 @@
   // Gets the PaginationModel owned by the AppsGridView.
   PaginationModel* GetAppsPaginationModel();
 
-  // Overridden from AppsGridViewDelegate:
-  void ActivateApp(AppListItem* item, int event_flags) override;
-  void CancelDragInActiveFolder() override;
-
   // Overridden from SearchBoxViewDelegate:
   void QueryChanged(SearchBoxView* sender) override;
   void BackButtonPressed() override;
diff --git a/ui/app_list/views/apps_container_view.cc b/ui/app_list/views/apps_container_view.cc
index de3fba6..8fcf6ec 100644
--- a/ui/app_list/views/apps_container_view.cc
+++ b/ui/app_list/views/apps_container_view.cc
@@ -17,29 +17,17 @@
 #include "ui/app_list/views/app_list_main_view.h"
 #include "ui/app_list/views/apps_grid_view.h"
 #include "ui/app_list/views/folder_background_view.h"
-#include "ui/app_list/views/indicator_chip_view.h"
+#include "ui/app_list/views/suggestions_container_view.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/events/event.h"
 #include "ui/strings/grit/ui_strings.h"
 
 namespace app_list {
 
-namespace {
-
-// Layout constants.
-constexpr int kAllAppsIndicatorExtraPadding = 2;
-
-}  // namespace
-
 AppsContainerView::AppsContainerView(AppListMainView* app_list_main_view,
                                      AppListModel* model)
     : is_fullscreen_app_list_enabled_(features::IsFullscreenAppListEnabled()) {
-  if (is_fullscreen_app_list_enabled_) {
-    all_apps_indicator_ = new IndicatorChipView(
-        l10n_util::GetStringUTF16(IDS_ALL_APPS_INDICATOR));
-    AddChildView(all_apps_indicator_);
-  }
-  apps_grid_view_ = new AppsGridView(app_list_main_view);
+  apps_grid_view_ = new AppsGridView(app_list_main_view->contents_view());
   if (is_fullscreen_app_list_enabled_) {
     apps_grid_view_->SetLayout(kPreferredColsFullscreen,
                                kPreferredRowsFullscreen);
@@ -133,16 +121,6 @@
 
   switch (show_state_) {
     case SHOW_APPS:
-      if (all_apps_indicator_) {
-        gfx::Rect indicator_rect(rect);
-        const gfx::Size indicator_size =
-            all_apps_indicator_->GetPreferredSize();
-        indicator_rect.Inset(
-            (indicator_rect.width() - indicator_size.width()) / 2, 0);
-        all_apps_indicator_->SetBoundsRect(indicator_rect);
-        rect.Inset(0, indicator_size.height() + kAllAppsIndicatorExtraPadding,
-                   0, 0);
-      }
       apps_grid_view_->SetBoundsRect(rect);
       break;
     case SHOW_ACTIVE_FOLDER:
diff --git a/ui/app_list/views/apps_container_view.h b/ui/app_list/views/apps_container_view.h
index 135a965b..72bbeac 100644
--- a/ui/app_list/views/apps_container_view.h
+++ b/ui/app_list/views/apps_container_view.h
@@ -27,7 +27,6 @@
 class AppListMainView;
 class AppListModel;
 class FolderBackgroundView;
-class IndicatorChipView;
 
 // AppsContainerView contains a root level AppsGridView to render the root level
 // app items, and a AppListFolderView to render the app items inside the
@@ -107,7 +106,6 @@
   void PrepareToShowApps(AppListFolderItem* folder_item);
 
   // The views below are owned by views hierarchy.
-  IndicatorChipView* all_apps_indicator_ = nullptr;
   AppsGridView* apps_grid_view_ = nullptr;
   AppListFolderView* app_list_folder_view_ = nullptr;
   FolderBackgroundView* folder_background_view_ = nullptr;
diff --git a/ui/app_list/views/apps_grid_view.cc b/ui/app_list/views/apps_grid_view.cc
index 00c3387..3bda39d 100644
--- a/ui/app_list/views/apps_grid_view.cc
+++ b/ui/app_list/views/apps_grid_view.cc
@@ -16,22 +16,30 @@
 #include "ui/app_list/app_list_folder_item.h"
 #include "ui/app_list/app_list_item.h"
 #include "ui/app_list/app_list_switches.h"
+#include "ui/app_list/app_list_view_delegate.h"
 #include "ui/app_list/pagination_controller.h"
 #include "ui/app_list/views/app_list_drag_and_drop_host.h"
 #include "ui/app_list/views/app_list_folder_view.h"
 #include "ui/app_list/views/app_list_item_view.h"
+#include "ui/app_list/views/app_list_main_view.h"
 #include "ui/app_list/views/apps_grid_view_delegate.h"
+#include "ui/app_list/views/contents_view.h"
+#include "ui/app_list/views/indicator_chip_view.h"
 #include "ui/app_list/views/page_switcher_horizontal.h"
 #include "ui/app_list/views/page_switcher_vertical.h"
 #include "ui/app_list/views/pulsing_block_view.h"
+#include "ui/app_list/views/suggestions_container_view.h"
+#include "ui/app_list/views/tile_item_view.h"
 #include "ui/app_list/views/top_icon_animation_view.h"
 #include "ui/aura/window.h"
 #include "ui/aura/window_event_dispatcher.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/events/event.h"
 #include "ui/gfx/animation/animation.h"
 #include "ui/gfx/geometry/vector2d.h"
 #include "ui/gfx/geometry/vector2d_conversions.h"
+#include "ui/strings/grit/ui_strings.h"
 #include "ui/views/border.h"
 #include "ui/views/controls/label.h"
 #include "ui/views/view_model_utils.h"
@@ -45,44 +53,51 @@
 // which point we rearrange the apps to their pre-drag configuration, as a drop
 // then would be canceled. We have a buffer to make it easier to drag apps to
 // other pages.
-const int kDragBufferPx = 20;
+constexpr int kDragBufferPx = 20;
 
 // Padding space in pixels between pages.
-const int kPagePadding = 40;
+constexpr int kPagePadding = 40;
 
 // Preferred tile size when showing in fixed layout.
-const int kPreferredTileWidth = 100;
-const int kPreferredTileHeight = 100;
+constexpr int kPreferredTileWidth = 100;
+constexpr int kPreferredTileHeight = 100;
 
 // Padding on each side of a tile.
-const int kTileLeftRightPadding = 10;
-const int kTileBottomPadding = 6;
-const int kTileTopPadding = 6;
-const int kTileLeftRightPaddingFullscreen = 12;
-const int kTileBottomPaddingFullscreen = 6;
-const int kTileTopPaddingFullscreen = 6;
+constexpr int kTileLeftRightPadding = 10;
+constexpr int kTileBottomPadding = 6;
+constexpr int kTileTopPadding = 6;
+constexpr int kTileLeftRightPaddingFullscreen = 12;
+constexpr int kTileBottomPaddingFullscreen = 6;
+constexpr int kTileTopPaddingFullscreen = 6;
 
 // Width in pixels of the area on the sides that triggers a page flip.
-const int kPageFlipZoneSize = 40;
+constexpr int kPageFlipZoneSize = 40;
 
 // Delay in milliseconds to do the page flip.
-const int kPageFlipDelayInMs = 1000;
+constexpr int kPageFlipDelayInMs = 1000;
 
 // The drag and drop proxy should get scaled by this factor.
-const float kDragAndDropProxyScale = 1.5f;
+constexpr float kDragAndDropProxyScale = 1.5f;
 
 // Delays in milliseconds to show folder dropping preview circle.
-const int kFolderDroppingDelay = 150;
+constexpr int kFolderDroppingDelay = 150;
 
 // Delays in milliseconds to show re-order preview.
-const int kReorderDelay = 120;
+constexpr int kReorderDelay = 120;
 
 // Delays in milliseconds to show folder item reparent UI.
-const int kFolderItemReparentDelay = 50;
+constexpr int kFolderItemReparentDelay = 50;
 
 // Radius of the circle, in which if entered, show folder dropping preview
 // UI.
-const int kFolderDroppingCircleRadius = 39;
+constexpr int kFolderDroppingCircleRadius = 39;
+
+// Padding between suggested apps tiles and all apps indicator.
+constexpr int kSuggestionsAllAppsIndicatorPadding = 28;
+
+// Extra padding needed between all apps indicator and all apps tiles on
+// non-first page.
+constexpr int kAllAppsIndicatorExtraPadding = 2;
 
 // Returns the size of a tile view excluding its padding.
 gfx::Size GetTileViewSize() {
@@ -209,33 +224,29 @@
 
 }  // namespace
 
-AppsGridView::AppsGridView(AppsGridViewDelegate* delegate)
-    : model_(NULL),
-      item_list_(NULL),
-      delegate_(delegate),
-      folder_delegate_(NULL),
-      page_switcher_view_(NULL),
-      cols_(0),
-      rows_per_page_(0),
-      selected_view_(NULL),
-      drag_view_(NULL),
-      drag_start_page_(-1),
-      drag_pointer_(NONE),
-      drop_attempt_(DROP_FOR_NONE),
-      drag_and_drop_host_(NULL),
-      forward_events_to_drag_and_drop_host_(false),
-      page_flip_target_(-1),
+AppsGridView::AppsGridView(ContentsView* contents_view)
+    : contents_view_(contents_view),
       page_flip_delay_in_ms_(kPageFlipDelayInMs),
       bounds_animator_(this),
-      activated_folder_item_view_(NULL),
-      dragging_for_reparent_item_(false),
       is_fullscreen_app_list_enabled_(features::IsFullscreenAppListEnabled()) {
+  DCHECK(contents_view_);
   SetPaintToLayer();
   // Clip any icons that are outside the grid view's bounds. These icons would
   // otherwise be visible to the user when the grid view is off screen.
   layer()->SetMasksToBounds(true);
   layer()->SetFillsBoundsOpaquely(false);
 
+  if (is_fullscreen_app_list_enabled_) {
+    suggested_apps_indicator_ = CreateIndicator(IDS_SUGGESTED_APPS_INDICATOR);
+
+    suggestions_container_ =
+        new SuggestionsContainerView(contents_view_, nullptr);
+    AddChildView(suggestions_container_);
+    UpdateSuggestions();
+
+    all_apps_indicator_ = CreateIndicator(IDS_ALL_APPS_INDICATOR);
+  }
+
   pagination_model_.SetTransitionDurations(kPageTransitionDurationInMs,
                                            kOverscrollPageTransitionDurationMs);
 
@@ -291,7 +302,8 @@
 }
 
 void AppsGridView::ResetForShowApps() {
-  activated_folder_item_view_ = NULL;
+  UpdateSuggestions();
+  activated_folder_item_view_ = nullptr;
   ClearDragState();
   layer()->SetOpacity(1.0f);
   SetVisible(true);
@@ -336,14 +348,14 @@
 void AppsGridView::ClearSelectedView(AppListItemView* view) {
   if (view && IsSelectedView(view)) {
     selected_view_->SchedulePaint();
-    selected_view_ = NULL;
+    selected_view_ = nullptr;
   }
 }
 
 void AppsGridView::ClearAnySelectedView() {
   if (selected_view_) {
     selected_view_->SchedulePaint();
-    selected_view_ = NULL;
+    selected_view_ = nullptr;
   }
 }
 
@@ -478,7 +490,7 @@
       // An EndDrag can be received during a reparent via a model change. This
       // is always a cancel and needs to be forwarded to the folder.
       DCHECK(cancel);
-      delegate_->CancelDragInActiveFolder();
+      contents_view_->app_list_main_view()->CancelDragInActiveFolder();
       return;
     }
 
@@ -631,7 +643,7 @@
       DeleteItemViewAtIndex(drag_view_index);
     }
   }
-  drag_view_ = NULL;
+  drag_view_ = nullptr;
   dragging_for_reparent_item_ = false;
 }
 
@@ -681,6 +693,26 @@
   if (bounds_animator_.IsAnimating())
     bounds_animator_.Cancel();
 
+  gfx::Rect rect(GetContentsBounds());
+  const gfx::Vector2d page_zero_offset = CalculateTransitionOffset(0);
+
+  LayoutSuggestedAppsIndicator(&rect);
+  if (suggestions_container_) {
+    gfx::Rect suggestions_rect(rect);
+    suggestions_rect.set_height(
+        suggestions_container_->GetHeightForWidth(suggestions_rect.width()));
+    suggestions_rect.Offset((suggestions_rect.width() - kGridTileWidth) / 2 -
+                                (kGridTileWidth + kGridTileSpacing) * 2,
+                            0);
+    suggestions_rect.Offset(page_zero_offset.x(), page_zero_offset.y());
+    suggestions_container_->SetBoundsRect(suggestions_rect);
+    rect.Inset(0,
+               suggestions_container_->GetPreferredSize().height() +
+                   kSuggestionsAllAppsIndicatorPadding,
+               0, 0);
+  }
+  LayoutAllAppsIndicator(&rect);
+
   CalculateIdealBounds();
   for (int i = 0; i < view_model_.view_size(); ++i) {
     AppListItemView* view = GetItemViewAt(i);
@@ -689,7 +721,6 @@
   }
   views::ViewModelUtils::SetViewBoundsToIdealBounds(pulsing_blocks_model_);
 
-  gfx::Rect rect(GetContentsBounds());
   if (is_fullscreen_app_list_enabled_) {
     const int page_switcher_width =
         page_switcher_view_->GetPreferredSize().width();
@@ -706,6 +737,13 @@
 
 bool AppsGridView::OnKeyPressed(const ui::KeyEvent& event) {
   bool handled = false;
+  if (is_fullscreen_app_list_enabled_ &&
+      suggestions_container_->selected_index() != -1) {
+    int selected_suggested_index = suggestions_container_->selected_index();
+    handled = suggestions_container_->GetTileItemView(selected_suggested_index)
+                  ->OnKeyPressed(event);
+  }
+
   if (selected_view_)
     handled = static_cast<views::View*>(selected_view_)->OnKeyPressed(event);
 
@@ -771,9 +809,9 @@
     CHECK_EQ(-1, view_model_.GetIndexOfView(details.child));
 
     if (selected_view_ == details.child)
-      selected_view_ = NULL;
+      selected_view_ = nullptr;
     if (activated_folder_item_view_ == details.child)
-      activated_folder_item_view_ = NULL;
+      activated_folder_item_view_ = nullptr;
 
     if (drag_view_ == details.child)
       EndDrag(true);
@@ -815,18 +853,85 @@
   SchedulePaint();
 }
 
-void AppsGridView::UpdatePaging() {
-  int total_page = view_model_.view_size() && tiles_per_page()
-                       ? (view_model_.view_size() - 1) / tiles_per_page() + 1
-                       : 0;
+IndicatorChipView* AppsGridView::CreateIndicator(
+    int indicator_text_message_id) {
+  IndicatorChipView* indicator = new IndicatorChipView(
+      l10n_util::GetStringUTF16(indicator_text_message_id));
+  AddChildView(indicator);
+  return indicator;
+}
 
-  pagination_model_.SetTotalPages(total_page);
+void AppsGridView::UpdateSuggestions() {
+  if (!suggestions_container_)
+    return;
+  suggestions_container_->SetResults(contents_view_->app_list_main_view()
+                                         ->view_delegate()
+                                         ->GetModel()
+                                         ->results());
+}
+
+void AppsGridView::LayoutSuggestedAppsIndicator(gfx::Rect* rect) {
+  if (!suggested_apps_indicator_)
+    return;
+
+  DCHECK(rect);
+  gfx::Rect indicator_rect(*rect);
+  const gfx::Size indicator_size =
+      suggested_apps_indicator_->GetPreferredSize();
+  indicator_rect.Inset((indicator_rect.width() - indicator_size.width()) / 2,
+                       0);
+  const gfx::Vector2d page_zero_offset = CalculateTransitionOffset(0);
+  indicator_rect.Offset(page_zero_offset.x(), page_zero_offset.y());
+  suggested_apps_indicator_->SetBoundsRect(indicator_rect);
+  rect->Inset(0, suggested_apps_indicator_->GetPreferredSize().height(), 0, 0);
+}
+
+void AppsGridView::LayoutAllAppsIndicator(gfx::Rect* rect) {
+  if (!all_apps_indicator_)
+    return;
+
+  DCHECK(rect);
+  gfx::Rect indicator_rect(*rect);
+  const gfx::Size indicator_size = all_apps_indicator_->GetPreferredSize();
+  indicator_rect.Inset((indicator_rect.width() - indicator_size.width()) / 2,
+                       0);
+  const gfx::Vector2d page_zero_offset = CalculateTransitionOffset(0);
+  indicator_rect.Offset(page_zero_offset.x(), page_zero_offset.y());
+  all_apps_indicator_->SetBoundsRect(indicator_rect);
+}
+
+int AppsGridView::TilesPerPage(int page) const {
+  if (is_fullscreen_app_list_enabled_ && page == 0)
+    return cols_ * (rows_per_page_ - 1);
+  return cols_ * rows_per_page_;
+}
+
+int AppsGridView::LastIndexOfPage(int page) const {
+  return TilesPerPage(page) - 1;
+}
+
+void AppsGridView::UpdatePaging() {
+  if (!view_model_.view_size() || !TilesPerPage(0)) {
+    pagination_model_.SetTotalPages(0);
+    return;
+  }
+
+  int total_pages = 0;
+  if (view_model_.view_size() <= TilesPerPage(0)) {
+    total_pages = 1;
+  } else {
+    total_pages =
+        (view_model_.view_size() - TilesPerPage(0) - 1) / TilesPerPage(1) + 2;
+  }
+
+  pagination_model_.SetTotalPages(total_pages);
 }
 
 void AppsGridView::UpdatePulsingBlockViews() {
   const int existing_items = item_list_ ? item_list_->item_count() : 0;
+  int current_page = pagination_model_.selected_page();
   const int available_slots =
-      tiles_per_page() - existing_items % tiles_per_page();
+      TilesPerPage(current_page) - existing_items % TilesPerPage(current_page);
   const int desired =
       model_->status() == AppListModel::STATUS_SYNCING ? available_slots : 0;
 
@@ -858,11 +963,18 @@
 
 AppsGridView::Index AppsGridView::GetIndexFromModelIndex(
     int model_index) const {
-  return Index(model_index / tiles_per_page(), model_index % tiles_per_page());
+  if (model_index < TilesPerPage(0))
+    return Index(0, model_index);
+
+  return Index(1 + (model_index - TilesPerPage(0)) / TilesPerPage(1),
+               (model_index - TilesPerPage(0)) % TilesPerPage(1));
 }
 
 int AppsGridView::GetModelIndexFromIndex(const Index& index) const {
-  return index.page * tiles_per_page() + index.slot;
+  if (index.page == 0)
+    return index.slot;
+
+  return TilesPerPage(0) + (index.page - 1) * TilesPerPage(1) + index.slot;
 }
 
 void AppsGridView::EnsureViewVisible(const Index& index) {
@@ -893,7 +1005,7 @@
 
 bool AppsGridView::IsValidIndex(const Index& index) const {
   return index.page >= 0 && index.page < pagination_model_.total_pages() &&
-         index.slot >= 0 && index.slot < tiles_per_page() &&
+         index.slot >= 0 && index.slot < TilesPerPage(index.page) &&
          GetModelIndexFromIndex(index) < view_model_.view_size();
 }
 
@@ -908,7 +1020,7 @@
 
 AppListItemView* AppsGridView::GetViewAtIndex(const Index& index) const {
   if (!IsValidIndex(index))
-    return NULL;
+    return nullptr;
 
   const int model_index = GetModelIndexFromIndex(index);
   return GetItemViewAt(model_index);
@@ -917,41 +1029,101 @@
 AppsGridView::Index AppsGridView::GetLastViewIndex() const {
   DCHECK_LT(0, view_model_.view_size());
   int view_index = view_model_.view_size() - 1;
-  return Index(view_index / tiles_per_page(), view_index % tiles_per_page());
+  return GetIndexFromModelIndex(view_index);
 }
 
 void AppsGridView::MoveSelected(int page_delta,
                                 int slot_x_delta,
                                 int slot_y_delta) {
-  if (!selected_view_)
-    return SetSelectedItemByIndex(Index(pagination_model_.selected_page(), 0));
+  if (!selected_view_) {
+    // If fullscreen app list is enabled and we are on the first page, moving
+    // selected should consider suggested apps tiles before all apps tiles.
+    int current_page = pagination_model_.selected_page();
+    if (!is_fullscreen_app_list_enabled_ || current_page != 0)
+      return SetSelectedItemByIndex(Index(current_page, 0));
+    if (HandleSuggestionsMove(page_delta, slot_x_delta, slot_y_delta))
+      return;
+  }
 
   const Index& selected = GetIndexOfView(selected_view_);
   int target_slot = selected.slot + slot_x_delta + slot_y_delta * cols_;
 
-  if (selected.slot % cols_ == 0 && slot_x_delta == -1) {
-    if (selected.page > 0) {
-      page_delta = -1;
-      target_slot = selected.slot + cols_ - 1;
-    } else {
-      target_slot = selected.slot;
+  if (!is_fullscreen_app_list_enabled_) {
+    if (selected.slot % cols_ == 0 && slot_x_delta == -1) {
+      if (selected.page > 0) {
+        page_delta = -1;
+        target_slot = selected.slot + cols_ - 1;
+      } else {
+        target_slot = selected.slot;
+      }
     }
-  }
 
-  if (selected.slot % cols_ == cols_ - 1 && slot_x_delta == 1) {
-    if (selected.page < pagination_model_.total_pages() - 1) {
+    if (selected.slot % cols_ == cols_ - 1 && slot_x_delta == 1) {
+      if (selected.page < pagination_model_.total_pages() - 1) {
+        page_delta = 1;
+        target_slot = selected.slot - cols_ + 1;
+      } else {
+        target_slot = selected.slot;
+      }
+    }
+  } else {
+    // Moving left from the first slot of all apps tiles should move focus to
+    // the last slot of previous page or last tile of suggested apps.
+    if (selected.slot == 0 && slot_x_delta == -1) {
+      if (selected.page == 0) {
+        suggestions_container_->SetSelectedIndex(
+            suggestions_container_->num_results() - 1);
+        ClearSelectedView(selected_view_);
+        return;
+      } else {
+        page_delta = -1;
+        target_slot = LastIndexOfPage(selected.page + page_delta);
+      }
+    }
+
+    // Moving right from last slot should flip to next page and focus on the
+    // first tile.
+    if (selected.slot == LastIndexOfPage(selected.page) && slot_x_delta == 1) {
       page_delta = 1;
-      target_slot = selected.slot - cols_ + 1;
-    } else {
-      target_slot = selected.slot;
+      target_slot = 0;
+    }
+
+    // Moving up from the first row of all apps tiles should move focus to the
+    // last row of previous page or suggested apps.
+    if (selected.slot / cols_ == 0 && slot_y_delta == -1) {
+      if (selected.page == 0) {
+        const int max_suggestion_index =
+            suggestions_container_->num_results() - 1;
+        int selected_index = std::min(max_suggestion_index, selected.slot);
+        suggestions_container_->SetSelectedIndex(selected_index);
+        ClearSelectedView(selected_view_);
+        return;
+      } else {
+        page_delta = -1;
+        target_slot = LastIndexOfPage(selected.page + page_delta) -
+                      (cols_ - 1 - selected.slot);
+      }
+    }
+
+    // Moving down from the last row of all apps tiles should move focus to the
+    // first row of next page if it exists.
+    if (LastIndexOfPage(selected.page) - selected.slot < cols_ &&
+        slot_y_delta == 1) {
+      if (selected.page < pagination_model_.total_pages() - 1) {
+        page_delta = 1;
+        target_slot =
+            (cols_ - 1) - (LastIndexOfPage(selected.page) - selected.slot);
+      } else {
+        target_slot = selected.slot;
+      }
     }
   }
 
-  // Clamp the target slot to the last item if we are moving to the last page
-  // but our target slot is past the end of the item list.
-  if (page_delta &&
-      selected.page + page_delta == pagination_model_.total_pages() - 1) {
-    int last_item_slot = (view_model_.view_size() - 1) % tiles_per_page();
+  // Clamp the target slot to the last item if we are moving in or to the last
+  // page but our target slot is past the end of the item list.
+  if (selected.page + page_delta == pagination_model_.total_pages() - 1) {
+    int last_item_slot =
+        GetIndexFromModelIndex(view_model_.view_size() - 1).slot;
     if (last_item_slot < target_slot) {
       target_slot = last_item_slot;
     }
@@ -962,6 +1134,48 @@
   SetSelectedItemByIndex(Index(target_page, target_slot));
 }
 
+bool AppsGridView::HandleSuggestionsMove(int page_delta,
+                                         int slot_x_delta,
+                                         int slot_y_delta) {
+  if (suggestions_container_->selected_index() == -1) {
+    suggestions_container_->SetSelectedIndex(0);
+    return true;
+  }
+
+  if (page_delta == -1 || slot_y_delta == -1)
+    return true;
+
+  if (slot_x_delta != 0) {
+    int new_index = suggestions_container_->selected_index() + slot_x_delta;
+    // Moving right out of |suggestions_container_| should give focus to the
+    // first tile of all apps.
+    if (new_index == suggestions_container_->num_results()) {
+      suggestions_container_->ClearSelectedIndex();
+      SetSelectedItemByIndex(Index(0, 0));
+    } else if (suggestions_container_->IsValidSelectionIndex(new_index)) {
+      suggestions_container_->SetSelectedIndex(new_index);
+    }
+    return true;
+  }
+
+  // Moving down from |suggestions_container_| should give focus to the first
+  // row of all apps.
+  if (slot_y_delta == 1) {
+    SetSelectedItemByIndex(Index(0, suggestions_container_->selected_index()));
+    suggestions_container_->ClearSelectedIndex();
+    return true;
+  }
+
+  // A page flip to next page from |suggestions_container_| should focus to
+  // the first tile of next page.
+  if (page_delta == 1) {
+    SetSelectedItemByIndex(Index(page_delta, 0));
+    suggestions_container_->ClearSelectedIndex();
+    return true;
+  }
+  return false;
+}
+
 const gfx::Vector2d AppsGridView::CalculateTransitionOffset(
     int page_of_view) const {
   gfx::Size grid_size = GetTileGridSize();
@@ -995,7 +1209,7 @@
       }
     }
   } else {
-    const int page_height = grid_size.height() + kPagePadding;
+    const int page_height = grid_size.height();
     if (page_of_view < current_page)
       y_offset = -page_height;
     else if (page_of_view > current_page)
@@ -1255,7 +1469,7 @@
 
     // Do not observe any data change since it is going to be hidden.
     item_list_->RemoveObserver(this);
-    item_list_ = NULL;
+    item_list_ = nullptr;
   }
 }
 
@@ -1364,7 +1578,7 @@
     // cleaning up the newly created AppListItemView, effectively claiming
     // ownership of the newly created drag view.
     drag_view_->OnDragEnded();
-    drag_view_ = NULL;
+    drag_view_ = nullptr;
   }
   ClearDragState();
   AnimateToIdealBounds();
@@ -1740,8 +1954,10 @@
 }
 
 void AppsGridView::CancelContextMenusOnCurrentPage() {
-  int start = pagination_model_.selected_page() * tiles_per_page();
-  int end = std::min(view_model_.view_size(), start + tiles_per_page());
+  Index start_index(pagination_model_.selected_page(), 0);
+  int start = GetModelIndexFromIndex(start_index);
+  int end =
+      std::min(view_model_.view_size(), start + TilesPerPage(start_index.page));
   for (int i = start; i < end; ++i)
     GetItemViewAt(i)->CancelContextMenu();
 }
@@ -1750,7 +1966,7 @@
   AppListItemView* item_view = GetItemViewAt(index);
   view_model_.Remove(index);
   if (item_view == drag_view_)
-    drag_view_ = NULL;
+    drag_view_ = nullptr;
   delete item_view;
 }
 
@@ -1767,23 +1983,22 @@
 
   if (strcmp(sender->GetClassName(), AppListItemView::kViewClassName))
     return;
-  AppListItemView* pressed_item_view = static_cast<AppListItemView*>(sender);
 
-  if (delegate_) {
-    // Always set the previous activated_folder_item_view_ to be visible. This
-    // prevents a case where the item would remain hidden due the
-    // |activated_folder_item_view_| changing during the animation. We only
-    // need to track |activated_folder_item_view_| in the root level grid view.
-    if (!folder_delegate_) {
-      if (activated_folder_item_view_)
-        activated_folder_item_view_->SetVisible(true);
-      if (IsFolderItem(pressed_item_view->item()))
-        activated_folder_item_view_ = pressed_item_view;
-      else
-        activated_folder_item_view_ = NULL;
-    }
-    delegate_->ActivateApp(pressed_item_view->item(), event.flags());
+  // Always set the previous activated_folder_item_view_ to be visible. This
+  // prevents a case where the item would remain hidden due the
+  // |activated_folder_item_view_| changing during the animation. We only
+  // need to track |activated_folder_item_view_| in the root level grid view.
+  AppListItemView* pressed_item_view = static_cast<AppListItemView*>(sender);
+  if (!folder_delegate_) {
+    if (activated_folder_item_view_)
+      activated_folder_item_view_->SetVisible(true);
+    if (IsFolderItem(pressed_item_view->item()))
+      activated_folder_item_view_ = pressed_item_view;
+    else
+      activated_folder_item_view_ = nullptr;
   }
+  contents_view_->app_list_main_view()->ActivateApp(pressed_item_view->item(),
+                                                    event.flags());
 }
 
 void AppsGridView::OnListItemAdded(size_t index, AppListItem* item) {
@@ -1893,17 +2108,37 @@
 
 gfx::Size AppsGridView::GetTileGridSize() const {
   gfx::Rect bounds = GetExpectedTileBounds(0, 0);
-  bounds.Union(GetExpectedTileBounds(rows_per_page_ - 1, cols_ - 1));
+  if (is_fullscreen_app_list_enabled_ && pagination_model_.selected_page() == 0)
+    bounds.Union(GetExpectedTileBounds(rows_per_page_ - 2, cols_ - 1));
+  else
+    bounds.Union(GetExpectedTileBounds(rows_per_page_ - 1, cols_ - 1));
+  bounds.Inset(0, -GetHeightOnTopOfAllAppsTiles(), 0, 0);
   bounds.Inset(GetTilePadding());
   return bounds.size();
 }
 
+int AppsGridView::GetHeightOnTopOfAllAppsTiles() const {
+  if (!is_fullscreen_app_list_enabled_)
+    return 0;
+
+  if (pagination_model_.selected_page() == 0) {
+    return suggested_apps_indicator_->GetPreferredSize().height() +
+           suggestions_container_->GetPreferredSize().height() +
+           kSuggestionsAllAppsIndicatorPadding +
+           all_apps_indicator_->GetPreferredSize().height() -
+           kTileTopPaddingFullscreen;
+  }
+  return all_apps_indicator_->GetPreferredSize().height() +
+         kAllAppsIndicatorExtraPadding;
+}
+
 gfx::Rect AppsGridView::GetExpectedTileBounds(int slot) const {
   return GetExpectedTileBounds(slot / cols_, slot % cols_);
 }
 
 gfx::Rect AppsGridView::GetExpectedTileBounds(int row, int col) const {
   gfx::Rect bounds(GetContentsBounds());
+  bounds.Inset(0, GetHeightOnTopOfAllAppsTiles(), 0, 0);
   const gfx::Size total_tile_size = GetTotalTileSize();
   gfx::Rect tile_bounds(gfx::Point(bounds.x() + col * total_tile_size.width(),
                                    bounds.y() + row * total_tile_size.height()),
@@ -1915,7 +2150,7 @@
 AppListItemView* AppsGridView::GetViewDisplayedAtSlotOnCurrentPage(
     int slot) const {
   if (slot < 0)
-    return NULL;
+    return nullptr;
 
   // Calculate the original bound of the tile at |index|.
   int row = slot / cols_;
@@ -1927,7 +2162,7 @@
     if (view->bounds() == tile_rect && view != drag_view_)
       return view;
   }
-  return NULL;
+  return nullptr;
 }
 
 void AppsGridView::SetAsFolderDroppingTarget(const Index& target_index,
diff --git a/ui/app_list/views/apps_grid_view.h b/ui/app_list/views/apps_grid_view.h
index 0c8512c..509c900 100644
--- a/ui/app_list/views/apps_grid_view.h
+++ b/ui/app_list/views/apps_grid_view.h
@@ -42,8 +42,10 @@
 
 class ApplicationDragAndDropHost;
 class AppListItemView;
-class AppsGridViewDelegate;
 class AppsGridViewFolderDelegate;
+class ContentsView;
+class IndicatorChipView;
+class SuggestionsContainerView;
 class PageSwitcher;
 class PaginationController;
 class PulsingBlockView;
@@ -62,9 +64,7 @@
     TOUCH,
   };
 
-  // Constructs the app icon grid view. |delegate| is the delegate of this
-  // view, which usually is the hosting AppListView.
-  explicit AppsGridView(AppsGridViewDelegate* delegate);
+  explicit AppsGridView(ContentsView* contents_view);
   ~AppsGridView() override;
 
   // Sets fixed layout parameters. After setting this, CalculateLayout below
@@ -213,6 +213,10 @@
 
   const AppListModel* model() const { return model_; }
 
+  SuggestionsContainerView* suggestions_container_for_test() const {
+    return suggestions_container_;
+  }
+
  private:
   friend class test::AppsGridViewTestApi;
 
@@ -241,7 +245,21 @@
     int slot;  // Which slot in the page an item view is in.
   };
 
-  int tiles_per_page() const { return cols_ * rows_per_page_; }
+  // Creates indicator based on the indicator text message id.
+  IndicatorChipView* CreateIndicator(int indicator_text_message_id);
+
+  // Updates suggestions from app list model.
+  void UpdateSuggestions();
+
+  // Helper method for layouting indicator based on the given bounds |rect|.
+  void LayoutSuggestedAppsIndicator(gfx::Rect* rect);
+  void LayoutAllAppsIndicator(gfx::Rect* rect);
+
+  // Returns all apps tiles per page based on |page|.
+  int TilesPerPage(int page) const;
+
+  // Returns the last index of |page|.
+  int LastIndexOfPage(int page) const;
 
   // Updates from model.
   void Update();
@@ -276,6 +294,12 @@
 
   void MoveSelected(int page_delta, int slot_x_delta, int slot_y_delta);
 
+  // Returns true if the given moving operation should be handled by
+  // |suggestions_container_|, otherwise false.
+  bool HandleSuggestionsMove(int page_delta,
+                             int slot_x_delta,
+                             int slot_y_delta);
+
   // Calculates the offset for |page_of_view| based on current page and
   // transition target page.
   const gfx::Vector2d CalculateTransitionOffset(int page_of_view) const;
@@ -406,6 +430,11 @@
   // slot if |point| is outside the page's bounds.
   Index GetNearestTileIndexForPoint(const gfx::Point& point) const;
 
+  // Gets height on top of the all apps tiles. For the first page, that includes
+  // suggested apps indicator, suggested apps tiles, all apps indicator
+  // views; For the non-first pages, that include all apps indicator view only.
+  int GetHeightOnTopOfAllAppsTiles() const;
+
   // Gets the bounds of the tile located at |slot| on the current page.
   gfx::Rect GetExpectedTileBounds(int slot) const;
 
@@ -448,25 +477,32 @@
   // Returns the target icon bounds for |drag_item_view| to fly back
   // to its parent |folder_item_view| in animation.
   gfx::Rect GetTargetIconRectInFolder(AppListItemView* drag_item_view,
-      AppListItemView* folder_item_view);
+                                      AppListItemView* folder_item_view);
 
   // Returns true if the grid view is under an OEM folder.
   bool IsUnderOEMFolder();
 
-  AppListModel* model_;  // Owned by AppListView.
-  AppListItemList* item_list_;  // Not owned.
-  AppsGridViewDelegate* delegate_;
+  AppListModel* model_ = nullptr;         // Owned by AppListView.
+  AppListItemList* item_list_ = nullptr;  // Not owned.
 
   // This can be NULL. Only grid views inside folders have a folder delegate.
-  AppsGridViewFolderDelegate* folder_delegate_;
+  AppsGridViewFolderDelegate* folder_delegate_ = nullptr;
 
   PaginationModel pagination_model_;
   // Must appear after |pagination_model_|.
   std::unique_ptr<PaginationController> pagination_controller_;
-  PageSwitcher* page_switcher_view_;  // Owned by views hierarchy.
+  PageSwitcher* page_switcher_view_ = nullptr;  // Owned by views hierarchy.
 
-  int cols_;
-  int rows_per_page_;
+  // Created by AppListMainView, owned by views hierarchy.
+  ContentsView* contents_view_ = nullptr;
+
+  // Views below are owned by views hierarchy.
+  IndicatorChipView* suggested_apps_indicator_ = nullptr;
+  SuggestionsContainerView* suggestions_container_ = nullptr;
+  IndicatorChipView* all_apps_indicator_ = nullptr;
+
+  int cols_ = 0;
+  int rows_per_page_ = 0;
 
   // List of app item views. There is a view per item in |model_|.
   views::ViewModelT<AppListItemView> view_model_;
@@ -474,9 +510,9 @@
   // List of pulsing block views.
   views::ViewModelT<PulsingBlockView> pulsing_blocks_model_;
 
-  AppListItemView* selected_view_;
+  AppListItemView* selected_view_ = nullptr;
 
-  AppListItemView* drag_view_;
+  AppListItemView* drag_view_ = nullptr;
 
   // The index of the drag_view_ when the drag starts.
   Index drag_view_init_index_;
@@ -491,9 +527,9 @@
   gfx::Point drag_view_start_;
 
   // Page the drag started on.
-  int drag_start_page_;
+  int drag_start_page_ = -1;
 
-  Pointer drag_pointer_;
+  Pointer drag_pointer_ = NONE;
 
   // The most recent reorder drop target.
   Index reorder_drop_target_;
@@ -506,7 +542,7 @@
   Index reorder_placeholder_;
 
   // The current action that ending a drag will perform.
-  DropAttempt drop_attempt_;
+  DropAttempt drop_attempt_ = DROP_FOR_NONE;
 
   // Timer for re-ordering the |drop_target_| and |drag_view_|.
   base::OneShotTimer reorder_timer_;
@@ -519,11 +555,11 @@
   base::OneShotTimer folder_item_reparent_timer_;
 
   // An application target drag and drop host which accepts dnd operations.
-  ApplicationDragAndDropHost* drag_and_drop_host_;
+  ApplicationDragAndDropHost* drag_and_drop_host_ = nullptr;
 
   // The drag operation is currently inside the dnd host and events get
   // forwarded.
-  bool forward_events_to_drag_and_drop_host_;
+  bool forward_events_to_drag_and_drop_host_ = false;
 
   // Last mouse drag location in this view's coordinates.
   gfx::Point last_drag_point_;
@@ -532,7 +568,7 @@
   base::OneShotTimer page_flip_timer_;
 
   // Target page to switch to when |page_flip_timer_| fires.
-  int page_flip_target_;
+  int page_flip_target_ = -1;
 
   // Delay in milliseconds of when |page_flip_timer_| should fire after user
   // drags an item near the edges.
@@ -541,14 +577,14 @@
   views::BoundsAnimator bounds_animator_;
 
   // The most recent activated folder item view.
-  AppListItemView* activated_folder_item_view_;
+  AppListItemView* activated_folder_item_view_ = nullptr;
 
   // Tracks if drag_view_ is dragged out of the folder container bubble
   // when dragging a item inside a folder.
-  bool drag_out_of_folder_container_;
+  bool drag_out_of_folder_container_ = false;
 
   // True if the drag_view_ item is a folder item being dragged for reparenting.
-  bool dragging_for_reparent_item_;
+  bool dragging_for_reparent_item_ = false;
 
   // True if the fullscreen app list feature is enabled.
   const bool is_fullscreen_app_list_enabled_;
diff --git a/ui/app_list/views/apps_grid_view_unittest.cc b/ui/app_list/views/apps_grid_view_unittest.cc
index 1f7535dd..6abf67b 100644
--- a/ui/app_list/views/apps_grid_view_unittest.cc
+++ b/ui/app_list/views/apps_grid_view_unittest.cc
@@ -15,17 +15,26 @@
 #include "base/run_loop.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_feature_list.h"
 #include "build/build_config.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/app_list/app_list_constants.h"
+#include "ui/app_list/app_list_features.h"
 #include "ui/app_list/app_list_folder_item.h"
 #include "ui/app_list/app_list_item.h"
 #include "ui/app_list/app_list_model.h"
 #include "ui/app_list/app_list_switches.h"
 #include "ui/app_list/pagination_model.h"
 #include "ui/app_list/test/app_list_test_model.h"
+#include "ui/app_list/test/app_list_test_view_delegate.h"
+#include "ui/app_list/test/test_search_result.h"
 #include "ui/app_list/views/app_list_item_view.h"
+#include "ui/app_list/views/app_list_main_view.h"
+#include "ui/app_list/views/app_list_view.h"
+#include "ui/app_list/views/apps_container_view.h"
 #include "ui/app_list/views/apps_grid_view_folder_delegate.h"
+#include "ui/app_list/views/contents_view.h"
+#include "ui/app_list/views/suggestions_container_view.h"
 #include "ui/app_list/views/test/apps_grid_view_test_api.h"
 #include "ui/events/event_utils.h"
 #include "ui/views/controls/label.h"
@@ -36,14 +45,11 @@
 
 namespace {
 
-const int kCols = 2;
-const int kRows = 2;
-const int kTilesPerPage = kCols * kRows;
+constexpr int kNumOfSuggestedApps = 3;
 
 class PageFlipWaiter : public PaginationModelObserver {
  public:
-  explicit PageFlipWaiter(PaginationModel* model)
-      : model_(model), wait_(false) {
+  explicit PageFlipWaiter(PaginationModel* model) : model_(model) {
     model_->AddObserver(this);
   }
 
@@ -77,66 +83,100 @@
   void TransitionChanged() override {}
 
   std::unique_ptr<base::RunLoop> ui_run_loop_;
-  PaginationModel* model_;
-  bool wait_;
+  PaginationModel* model_ = nullptr;
+  bool wait_ = false;
   std::string selected_pages_;
 
   DISALLOW_COPY_AND_ASSIGN(PageFlipWaiter);
 };
 
+class TestSuggestedSearchResult : public TestSearchResult {
+ public:
+  TestSuggestedSearchResult() { set_display_type(DISPLAY_RECOMMENDATION); }
+  ~TestSuggestedSearchResult() override {}
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TestSuggestedSearchResult);
+};
+
 }  // namespace
 
-class AppsGridViewTest : public views::ViewsTestBase {
+class AppsGridViewTest : public views::ViewsTestBase,
+                         public testing::WithParamInterface<bool> {
  public:
-  AppsGridViewTest() {}
-  ~AppsGridViewTest() override {}
+  AppsGridViewTest() = default;
+  ~AppsGridViewTest() override = default;
 
   // testing::Test overrides:
   void SetUp() override {
     views::ViewsTestBase::SetUp();
-    model_.reset(new AppListTestModel);
-    model_->SetFoldersEnabled(true);
 
-    apps_grid_view_.reset(new AppsGridView(NULL));
-    apps_grid_view_->SetLayout(kCols, kRows);
-    apps_grid_view_->SetBoundsRect(
-        gfx::Rect(apps_grid_view_->GetPreferredSize()));
-    apps_grid_view_->SetModel(model_.get());
-    apps_grid_view_->SetItemList(model_->top_level_item_list());
+    // If the current test is parameterized.
+    if (testing::UnitTest::GetInstance()->current_test_info()->value_param()) {
+      test_with_fullscreen_ = GetParam();
+      if (test_with_fullscreen_)
+        EnableFullscreenAppList();
+    }
 
-    test_api_.reset(new AppsGridViewTestApi(apps_grid_view_.get()));
+    gfx::NativeView parent = GetContext();
+    delegate_.reset(new AppListTestViewDelegate);
+    app_list_view_ = new AppListView(delegate_.get());
+
+    // Initialize around a point that ensures the window is wholly shown.
+    app_list_view_->Initialize(parent, 0, false, false);
+    ContentsView* contents_view =
+        app_list_view_->app_list_main_view()->contents_view();
+    apps_grid_view_ = contents_view->apps_container_view()->apps_grid_view();
+    gfx::Size size = apps_grid_view_->GetPreferredSize();
+    app_list_view_->MaybeSetAnchorPoint(
+        gfx::Point(size.width() / 2, size.height() / 2));
+    app_list_view_->GetWidget()->Show();
+
+    model_ = delegate_->GetTestModel();
+    suggestions_container_ = apps_grid_view_->suggestions_container_for_test();
+    for (size_t i = 0; i < kNumOfSuggestedApps; ++i)
+      model_->results()->Add(base::MakeUnique<TestSuggestedSearchResult>());
+    // Needed to update suggestions from |model_|.
+    apps_grid_view_->ResetForShowApps();
+
+    // Set app list view to show all apps page to test AppsGridView.
+    contents_view->SetActiveState(AppListModel::STATE_APPS);
+    contents_view->Layout();
+
+    test_api_.reset(new AppsGridViewTestApi(apps_grid_view_));
   }
   void TearDown() override {
-    apps_grid_view_.reset();  // Release apps grid view before models.
+    app_list_view_->GetWidget()->Close();
     views::ViewsTestBase::TearDown();
   }
 
  protected:
-  AppListItemView* GetItemViewAt(int index) {
-    return static_cast<AppListItemView*>(
-        test_api_->GetViewAtModelIndex(index));
+  void EnableFullscreenAppList() {
+    scoped_feature_list_.InitAndEnableFeature(
+        features::kEnableFullscreenAppList);
   }
 
-  AppListItemView* GetItemViewForPoint(const gfx::Point& point) {
+  AppListItemView* GetItemViewAt(int index) const {
+    return static_cast<AppListItemView*>(test_api_->GetViewAtModelIndex(index));
+  }
+
+  AppListItemView* GetItemViewForPoint(const gfx::Point& point) const {
     for (size_t i = 0; i < model_->top_level_item_list()->item_count(); ++i) {
       AppListItemView* view = GetItemViewAt(i);
       if (view->bounds().Contains(point))
         return view;
     }
-    return NULL;
+    return nullptr;
   }
 
-  gfx::Rect GetItemTileRectAt(int row, int col) {
+  gfx::Rect GetItemTileRectAt(int row, int col) const {
     DCHECK_GT(model_->top_level_item_list()->item_count(), 0u);
-
-    gfx::Insets insets(apps_grid_view_->GetInsets());
-    gfx::Rect rect(gfx::Point(insets.left(), insets.top()),
-                   AppsGridView::GetTotalTileSize());
-    rect.Offset(col * rect.width(), row * rect.height());
-    return rect;
+    return test_api_->GetItemTileRectAt(row, col);
   }
 
-  PaginationModel* GetPaginationModel() {
+  int GetTilesPerPage(int page) const { return test_api_->TilesPerPage(page); }
+
+  PaginationModel* GetPaginationModel() const {
     return apps_grid_view_->pagination_model();
   }
 
@@ -167,18 +207,28 @@
     apps_grid_view_->OnKeyPressed(key_event);
   }
 
-  std::unique_ptr<AppListTestModel> model_;
-  std::unique_ptr<AppsGridView> apps_grid_view_;
+  AppListView* app_list_view_ = nullptr;    // Owned by native widget.
+  AppsGridView* apps_grid_view_ = nullptr;  // Owned by |app_list_view_|.
+  SuggestionsContainerView* suggestions_container_ =
+      nullptr;  // Owned by |apps_grid_view_|.
+  std::unique_ptr<AppListTestViewDelegate> delegate_;
+  AppListTestModel* model_ = nullptr;  // Owned by |delegate_|.
   std::unique_ptr<AppsGridViewTestApi> test_api_;
+  bool test_with_fullscreen_ = false;
+  base::test::ScopedFeatureList scoped_feature_list_;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(AppsGridViewTest);
 };
 
+// Instantiate the Boolean which is used to toggle the Fullscreen app list in
+// the parameterized tests.
+INSTANTIATE_TEST_CASE_P(, AppsGridViewTest, testing::Bool());
+
 class TestAppsGridViewFolderDelegate : public AppsGridViewFolderDelegate {
  public:
-  TestAppsGridViewFolderDelegate() : show_bubble_(false) {}
-  ~TestAppsGridViewFolderDelegate() override {}
+  TestAppsGridViewFolderDelegate() = default;
+  ~TestAppsGridViewFolderDelegate() override = default;
 
   // Overridden from AppsGridViewFolderDelegate:
   void UpdateFolderViewBackground(bool show_bubble) override {
@@ -207,15 +257,21 @@
   bool show_bubble() { return show_bubble_; }
 
  private:
-  bool show_bubble_;
+  bool show_bubble_ = false;
 
   DISALLOW_COPY_AND_ASSIGN(TestAppsGridViewFolderDelegate);
 };
 
-TEST_F(AppsGridViewTest, CreatePage) {
+TEST_P(AppsGridViewTest, CreatePage) {
   // Fully populates a page.
   const int kPages = 1;
-  model_->PopulateApps(kPages * kTilesPerPage);
+  if (test_with_fullscreen_) {
+    EXPECT_EQ(kNumOfSuggestedApps, suggestions_container_->num_results());
+    int kExpectedTilesOnFirstPage =
+        apps_grid_view_->cols() * (apps_grid_view_->rows_per_page() - 1);
+    EXPECT_EQ(kExpectedTilesOnFirstPage, GetTilesPerPage(kPages - 1));
+  }
+  model_->PopulateApps(kPages * GetTilesPerPage(kPages - 1));
   EXPECT_EQ(kPages, GetPaginationModel()->total_pages());
 
   // Adds one more and gets a new page created.
@@ -223,9 +279,9 @@
   EXPECT_EQ(kPages + 1, GetPaginationModel()->total_pages());
 }
 
-TEST_F(AppsGridViewTest, EnsureHighlightedVisible) {
+TEST_P(AppsGridViewTest, EnsureHighlightedVisible) {
   const int kPages = 3;
-  model_->PopulateApps(kPages * kTilesPerPage);
+  model_->PopulateApps(GetTilesPerPage(0) + (kPages - 1) * GetTilesPerPage(1));
   EXPECT_EQ(kPages, GetPaginationModel()->total_pages());
   EXPECT_EQ(0, GetPaginationModel()->selected_page());
 
@@ -233,11 +289,11 @@
   // selected.
   model_->HighlightItemAt(0);
   EXPECT_EQ(0, GetPaginationModel()->selected_page());
-  model_->HighlightItemAt(kTilesPerPage - 1);
+  model_->HighlightItemAt(GetTilesPerPage(0) - 1);
   EXPECT_EQ(0, GetPaginationModel()->selected_page());
 
   // Highlight first one on 2nd page and 2nd page should be selected.
-  model_->HighlightItemAt(kTilesPerPage + 1);
+  model_->HighlightItemAt(GetTilesPerPage(1) + 1);
   EXPECT_EQ(1, GetPaginationModel()->selected_page());
 
   // Highlight last one in the model and last page should be selected.
@@ -245,7 +301,7 @@
   EXPECT_EQ(kPages - 1, GetPaginationModel()->selected_page());
 }
 
-TEST_F(AppsGridViewTest, RemoveSelectedLastApp) {
+TEST_P(AppsGridViewTest, RemoveSelectedLastApp) {
   const int kTotalItems = 2;
   const int kLastItemIndex = kTotalItems - 1;
 
@@ -291,8 +347,7 @@
   SimulateDrag(AppsGridView::MOUSE, from, to);
   model_->DeleteItem(model_->GetItemName(0));
   apps_grid_view_->EndDrag(false);
-  EXPECT_EQ(std::string("Item 1,Item 2,Item 3"),
-            model_->GetModelContent());
+  EXPECT_EQ(std::string("Item 1,Item 2,Item 3"), model_->GetModelContent());
   test_api_->LayoutToIdealBounds();
 
   // Adding a launcher item cancels the drag and respects the order.
@@ -434,7 +489,8 @@
   test_api_->LayoutToIdealBounds();
 
   // The grid now looks like | blank | folder |.
-  EXPECT_EQ(NULL, GetItemViewForPoint(GetItemTileRectAt(0, 0).CenterPoint()));
+  EXPECT_EQ(nullptr,
+            GetItemViewForPoint(GetItemTileRectAt(0, 0).CenterPoint()));
   EXPECT_EQ(folder_view,
             GetItemViewForPoint(GetItemTileRectAt(0, 1).CenterPoint()));
 
@@ -454,6 +510,8 @@
 }
 
 TEST_F(AppsGridViewTest, MouseDragItemReorder) {
+  // Using a simulated 2x2 layout for the test.
+  apps_grid_view_->SetLayout(2, 2);
   model_->PopulateApps(4);
   EXPECT_EQ(4u, model_->top_level_item_list()->item_count());
   EXPECT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"),
@@ -475,37 +533,44 @@
             model_->GetModelContent());
 
   // Drag left, past the folder dropping circle.
+  gfx::Vector2d last_drag_vector(drag_vector);
   drag_vector.set_x(-3 * half_tile_width + 4);
-  SimulateDrag(AppsGridView::MOUSE, top_right, top_right + drag_vector);
+  SimulateDrag(AppsGridView::MOUSE, top_right + last_drag_vector,
+               top_right + drag_vector);
   apps_grid_view_->EndDrag(false);
   EXPECT_EQ(std::string("Item 1,Item 0,Item 2,Item 3"),
             model_->GetModelContent());
 
   // Drag down, between apps 2 and 3. The gap should open up, making space for
-  // app 0 in the bottom left.
+  // app 1 in the bottom left.
+  last_drag_vector = drag_vector;
   drag_vector.set_x(-half_tile_width);
   drag_vector.set_y(tile_height);
-  SimulateDrag(AppsGridView::MOUSE, top_right, top_right + drag_vector);
+  SimulateDrag(AppsGridView::MOUSE, top_right + last_drag_vector,
+               top_right + drag_vector);
   apps_grid_view_->EndDrag(false);
-  EXPECT_EQ(std::string("Item 1,Item 2,Item 0,Item 3"),
+  EXPECT_EQ(std::string("Item 0,Item 2,Item 1,Item 3"),
             model_->GetModelContent());
 
-  // Drag up, between apps 1 and 2. The gap should open up, making space for app
-  // 0 in the top right.
-  gfx::Point bottom_left = GetItemTileRectAt(1, 0).CenterPoint();
-  drag_vector.set_x(half_tile_width);
-  drag_vector.set_y(-tile_height);
-  SimulateDrag(AppsGridView::MOUSE, bottom_left, bottom_left + drag_vector);
+  // Drag up, between apps 0 and 2. The gap should open up, making space for app
+  // 1 in the top right.
+  last_drag_vector = drag_vector;
+  drag_vector.set_x(-half_tile_width);
+  drag_vector.set_y(0);
+  SimulateDrag(AppsGridView::MOUSE, top_right + last_drag_vector,
+               top_right + drag_vector);
   apps_grid_view_->EndDrag(false);
-  EXPECT_EQ(std::string("Item 1,Item 0,Item 2,Item 3"),
+  EXPECT_EQ(std::string("Item 0,Item 1,Item 2,Item 3"),
             model_->GetModelContent());
 
   // Dragging down past the last app should reorder to the last position.
+  last_drag_vector = drag_vector;
   drag_vector.set_x(half_tile_width);
   drag_vector.set_y(2 * tile_height);
-  SimulateDrag(AppsGridView::MOUSE, top_right, top_right + drag_vector);
+  SimulateDrag(AppsGridView::MOUSE, top_right + last_drag_vector,
+               top_right + drag_vector);
   apps_grid_view_->EndDrag(false);
-  EXPECT_EQ(std::string("Item 1,Item 2,Item 3,Item 0"),
+  EXPECT_EQ(std::string("Item 0,Item 2,Item 3,Item 1"),
             model_->GetModelContent());
 }
 
@@ -533,7 +598,7 @@
   test_api_->LayoutToIdealBounds();
 }
 
-TEST_F(AppsGridViewTest, MouseDragWithCancelDeleteAddItem) {
+TEST_P(AppsGridViewTest, MouseDragWithCancelDeleteAddItem) {
   size_t kTotalItems = 4;
   model_->PopulateApps(kTotalItems);
   EXPECT_EQ(model_->top_level_item_list()->item_count(), kTotalItems);
@@ -573,13 +638,13 @@
   PageFlipWaiter page_flip_waiter(GetPaginationModel());
 
   const int kPages = 3;
-  model_->PopulateApps(kPages * kTilesPerPage);
+  model_->PopulateApps(GetTilesPerPage(0) + (kPages - 1) * GetTilesPerPage(1));
   EXPECT_EQ(kPages, GetPaginationModel()->total_pages());
   EXPECT_EQ(0, GetPaginationModel()->selected_page());
 
   gfx::Point from = GetItemTileRectAt(0, 0).CenterPoint();
-  gfx::Point to = gfx::Point(apps_grid_view_->width(),
-                             apps_grid_view_->height() / 2);
+  gfx::Point to =
+      gfx::Point(apps_grid_view_->width(), apps_grid_view_->height() / 2);
 
   // Drag to right edge.
   page_flip_waiter.Reset();
@@ -619,8 +684,8 @@
   gfx::Point mouse_from = GetItemTileRectAt(0, 0).CenterPoint();
   gfx::Point mouse_to = GetItemTileRectAt(0, 1).CenterPoint();
 
-  gfx::Point touch_from = GetItemTileRectAt(1, 0).CenterPoint();
-  gfx::Point touch_to = GetItemTileRectAt(1, 1).CenterPoint();
+  gfx::Point touch_from = GetItemTileRectAt(0, 2).CenterPoint();
+  gfx::Point touch_to = GetItemTileRectAt(0, 3).CenterPoint();
 
   // Starts a mouse drag first then a touch drag.
   SimulateDrag(AppsGridView::MOUSE, mouse_from, mouse_to);
@@ -641,7 +706,7 @@
   test_api_->LayoutToIdealBounds();
 }
 
-TEST_F(AppsGridViewTest, UpdateFolderBackgroundOnCancelDrag) {
+TEST_P(AppsGridViewTest, UpdateFolderBackgroundOnCancelDrag) {
   const int kTotalItems = 4;
   TestAppsGridViewFolderDelegate folder_delegate;
   apps_grid_view_->set_folder_delegate(&folder_delegate);
@@ -661,18 +726,24 @@
             model_->GetModelContent());
 }
 
-TEST_F(AppsGridViewTest, HighlightWithKeyboard) {
+TEST_P(AppsGridViewTest, HighlightWithKeyboard) {
+  if (test_with_fullscreen_)
+    return;
+
   const int kPages = 3;
-  const int kItems = (kPages - 1) * kTilesPerPage + 1;
+  const int kItems = GetTilesPerPage(0) + GetTilesPerPage(1) + 1;
   model_->PopulateApps(kItems);
+  EXPECT_EQ(kPages, GetPaginationModel()->total_pages());
 
   const int first_index = 0;
   const int last_index = kItems - 1;
-  const int last_index_on_page1_first_row = kRows - 1;
-  const int last_index_on_page1 = kTilesPerPage - 1;
-  const int first_index_on_page2 = kTilesPerPage;
-  const int first_index_on_page2_last_row = 2 * kTilesPerPage - kRows;
-  const int last_index_on_page2_last_row = 2 * kTilesPerPage - 1;
+  const int last_index_on_page1_first_row =
+      apps_grid_view_->rows_per_page() - 1;
+  const int last_index_on_page1 = GetTilesPerPage(0) - 1;
+  const int first_index_on_page2 = GetTilesPerPage(1);
+  const int first_index_on_page2_last_row =
+      2 * GetTilesPerPage(1) - apps_grid_view_->cols();
+  const int last_index_on_page2_last_row = 2 * GetTilesPerPage(1) - 1;
 
   // Try moving off the item beyond the first one.
   apps_grid_view_->SetSelectedView(GetItemViewAt(first_index));
@@ -692,54 +763,162 @@
   // row and vice versa.
   apps_grid_view_->SetSelectedView(GetItemViewAt(last_index_on_page1));
   SimulateKeyPress(ui::VKEY_RIGHT);
-  EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
-      first_index_on_page2_last_row)));
+  EXPECT_TRUE(apps_grid_view_->IsSelectedView(
+      GetItemViewAt(first_index_on_page2_last_row)));
   SimulateKeyPress(ui::VKEY_LEFT);
-  EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
-      last_index_on_page1)));
+  EXPECT_TRUE(
+      apps_grid_view_->IsSelectedView(GetItemViewAt(last_index_on_page1)));
 
   // Up/down on page boundary does nothing.
   apps_grid_view_->SetSelectedView(GetItemViewAt(last_index_on_page1));
   SimulateKeyPress(ui::VKEY_DOWN);
-  EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
-      last_index_on_page1)));
+  EXPECT_TRUE(
+      apps_grid_view_->IsSelectedView(GetItemViewAt(last_index_on_page1)));
   apps_grid_view_->SetSelectedView(
       GetItemViewAt(first_index_on_page2_last_row));
-  apps_grid_view_->
-      SetSelectedView(GetItemViewAt(last_index_on_page1_first_row));
+  apps_grid_view_->SetSelectedView(
+      GetItemViewAt(last_index_on_page1_first_row));
   SimulateKeyPress(ui::VKEY_UP);
-  EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
-      last_index_on_page1_first_row)));
+  EXPECT_TRUE(apps_grid_view_->IsSelectedView(
+      GetItemViewAt(last_index_on_page1_first_row)));
 
   // Page up and down should go to the same item on the next and last page.
   apps_grid_view_->SetSelectedView(GetItemViewAt(first_index_on_page2));
   SimulateKeyPress(ui::VKEY_PRIOR);
-  EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
-      first_index)));
+  EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(first_index)));
   SimulateKeyPress(ui::VKEY_NEXT);
-  EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
-      first_index_on_page2)));
+  EXPECT_TRUE(
+      apps_grid_view_->IsSelectedView(GetItemViewAt(first_index_on_page2)));
 
   // Moving onto a page with too few apps to support the expected index snaps
   // to the last available index.
   apps_grid_view_->SetSelectedView(GetItemViewAt(last_index_on_page2_last_row));
   SimulateKeyPress(ui::VKEY_RIGHT);
-  EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
-      last_index)));
+  EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(last_index)));
   apps_grid_view_->SetSelectedView(GetItemViewAt(last_index_on_page2_last_row));
   SimulateKeyPress(ui::VKEY_NEXT);
-  EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
-      last_index)));
+  EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(last_index)));
 
   // After page switch, arrow keys select first item on current page.
   apps_grid_view_->SetSelectedView(GetItemViewAt(first_index));
   GetPaginationModel()->SelectPage(1, false);
   SimulateKeyPress(ui::VKEY_LEFT);
-  EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(
-      first_index_on_page2)));
+  EXPECT_TRUE(
+      apps_grid_view_->IsSelectedView(GetItemViewAt(first_index_on_page2)));
 }
 
-TEST_F(AppsGridViewTest, ItemLabelShortNameOverride) {
+TEST_P(AppsGridViewTest, MoveSelectedOnAllAppsTiles) {
+  if (!test_with_fullscreen_)
+    return;
+
+  const int kItemsOnSecondPage = 3;
+  const int kAllAppsItems = GetTilesPerPage(0) + kItemsOnSecondPage;
+  const int kLastIndexOfFirstPage = GetTilesPerPage(0) - 1;
+  const int kFirstIndexOfLastRowFirstPage =
+      GetTilesPerPage(0) - apps_grid_view_->cols();
+  model_->PopulateApps(kAllAppsItems);
+
+  // Tests moving left from the first tile on the first page.
+  apps_grid_view_->SetSelectedView(GetItemViewAt(0));
+  SimulateKeyPress(ui::VKEY_LEFT);
+  EXPECT_FALSE(apps_grid_view_->has_selected_view());
+  EXPECT_EQ(suggestions_container_->num_results() - 1,
+            suggestions_container_->selected_index());
+  suggestions_container_->ClearSelectedIndex();
+
+  // Tests moving left from the first tile on the second page.
+  apps_grid_view_->SetSelectedView(GetItemViewAt(GetTilesPerPage(0)));
+  SimulateKeyPress(ui::VKEY_LEFT);
+  EXPECT_TRUE(
+      apps_grid_view_->IsSelectedView(GetItemViewAt(kLastIndexOfFirstPage)));
+
+  // Tests moving right from the last slot on the first page.
+  apps_grid_view_->SetSelectedView(GetItemViewAt(kLastIndexOfFirstPage));
+  SimulateKeyPress(ui::VKEY_RIGHT);
+  EXPECT_TRUE(
+      apps_grid_view_->IsSelectedView(GetItemViewAt(GetTilesPerPage(0))));
+
+  // Tests moving up from the first row on the first page.
+  apps_grid_view_->SetSelectedView(GetItemViewAt(1));
+  SimulateKeyPress(ui::VKEY_UP);
+  EXPECT_FALSE(apps_grid_view_->has_selected_view());
+  EXPECT_EQ(1, suggestions_container_->selected_index());
+  suggestions_container_->ClearSelectedIndex();
+
+  // Tests moving up from the first row on the second page.
+  apps_grid_view_->SetSelectedView(GetItemViewAt(kAllAppsItems - 1));
+  SimulateKeyPress(ui::VKEY_UP);
+  int expected_index =
+      GetTilesPerPage(0) - 1 - (apps_grid_view_->cols() - kItemsOnSecondPage);
+  EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(expected_index)));
+
+  // Tests moving down from the last row on the first page.
+  apps_grid_view_->SetSelectedView(
+      GetItemViewAt(kFirstIndexOfLastRowFirstPage));
+  SimulateKeyPress(ui::VKEY_DOWN);
+  EXPECT_TRUE(
+      apps_grid_view_->IsSelectedView(GetItemViewAt(GetTilesPerPage(0))));
+
+  // Tests moving down if no direct tile exists, clamp to the last item.
+  apps_grid_view_->SetSelectedView(GetItemViewAt(kLastIndexOfFirstPage));
+  SimulateKeyPress(ui::VKEY_DOWN);
+  EXPECT_TRUE(
+      apps_grid_view_->IsSelectedView(GetItemViewAt(kAllAppsItems - 1)));
+}
+
+TEST_P(AppsGridViewTest, HandleSuggestionsMove) {
+  if (!test_with_fullscreen_)
+    return;
+
+  // Tests that a non-up arrow key would move focus to the first tile of
+  // suggestions container, and all apps grid view doesn't have focus.
+  const int kPages = 2;
+  const int kAllAppsItems = GetTilesPerPage(0) + 1;
+  model_->PopulateApps(kAllAppsItems);
+  SimulateKeyPress(ui::VKEY_UP);
+  EXPECT_EQ(-1, suggestions_container_->selected_index());
+  EXPECT_FALSE(apps_grid_view_->has_selected_view());
+  SimulateKeyPress(ui::VKEY_DOWN);
+  EXPECT_EQ(0, suggestions_container_->selected_index());
+  EXPECT_FALSE(apps_grid_view_->has_selected_view());
+
+  // Tests moving to previous page and moving up.
+  SimulateKeyPress(ui::VKEY_PRIOR);
+  EXPECT_EQ(0, suggestions_container_->selected_index());
+  SimulateKeyPress(ui::VKEY_UP);
+  EXPECT_EQ(0, suggestions_container_->selected_index());
+
+  // Tests moving left, moving right and moving right out of suggestions.
+  SimulateKeyPress(ui::VKEY_LEFT);
+  EXPECT_EQ(0, suggestions_container_->selected_index());
+  SimulateKeyPress(ui::VKEY_RIGHT);
+  SimulateKeyPress(ui::VKEY_RIGHT);
+  EXPECT_EQ(kNumOfSuggestedApps - 1, suggestions_container_->selected_index());
+  SimulateKeyPress(ui::VKEY_RIGHT);
+  EXPECT_EQ(-1, suggestions_container_->selected_index());
+  EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(0)));
+
+  // Tests moving down from |suggestions_container_|.
+  apps_grid_view_->ClearAnySelectedView();
+  SimulateKeyPress(ui::VKEY_RIGHT);
+  SimulateKeyPress(ui::VKEY_RIGHT);
+  EXPECT_EQ(1, suggestions_container_->selected_index());
+  SimulateKeyPress(ui::VKEY_DOWN);
+  EXPECT_EQ(-1, suggestions_container_->selected_index());
+  EXPECT_TRUE(apps_grid_view_->IsSelectedView(GetItemViewAt(1)));
+
+  // Tests moving to next page.
+  apps_grid_view_->ClearAnySelectedView();
+  SimulateKeyPress(ui::VKEY_LEFT);
+  EXPECT_EQ(0, suggestions_container_->selected_index());
+  SimulateKeyPress(ui::VKEY_NEXT);
+  EXPECT_EQ(-1, suggestions_container_->selected_index());
+  EXPECT_TRUE(
+      apps_grid_view_->IsSelectedView(GetItemViewAt(kAllAppsItems - 1)));
+  EXPECT_EQ(kPages - 1, GetPaginationModel()->selected_page());
+}
+
+TEST_P(AppsGridViewTest, ItemLabelShortNameOverride) {
   // If the app's full name and short name differ, the title label's tooltip
   // should always be the full name of the app.
   std::string expected_text("xyz");
@@ -757,7 +936,7 @@
   EXPECT_EQ(expected_text, base::UTF16ToUTF8(title_label->text()));
 }
 
-TEST_F(AppsGridViewTest, ItemLabelNoShortName) {
+TEST_P(AppsGridViewTest, ItemLabelNoShortName) {
   // If the app's full name and short name are the same, use the default tooltip
   // behavior of the label (only show a tooltip if the title is truncated).
   std::string title("a");
@@ -768,8 +947,8 @@
   AppListItemView* item_view = GetItemViewAt(0);
   ASSERT_TRUE(item_view);
   const views::Label* title_label = item_view->title();
-  EXPECT_FALSE(title_label->GetTooltipText(
-      title_label->bounds().CenterPoint(), &actual_tooltip));
+  EXPECT_FALSE(title_label->GetTooltipText(title_label->bounds().CenterPoint(),
+                                           &actual_tooltip));
   EXPECT_EQ(title, base::UTF16ToUTF8(title_label->text()));
 }
 
diff --git a/ui/app_list/views/test/apps_grid_view_test_api.cc b/ui/app_list/views/test/apps_grid_view_test_api.cc
index cd38a19..06d79c4 100644
--- a/ui/app_list/views/test/apps_grid_view_test_api.cc
+++ b/ui/app_list/views/test/apps_grid_view_test_api.cc
@@ -36,6 +36,10 @@
   view_->Layout();
 }
 
+gfx::Rect AppsGridViewTestApi::GetItemTileRectAt(int row, int col) const {
+  return view_->GetExpectedTileBounds(row, col);
+}
+
 void AppsGridViewTestApi::SetPageFlipDelay(int page_flip_delay_in_ms) {
   view_->page_flip_delay_in_ms_ = page_flip_delay_in_ms;
 }
@@ -50,5 +54,9 @@
          view_->pagination_model()->has_transition();
 }
 
+int AppsGridViewTestApi::TilesPerPage(int page) const {
+  return view_->TilesPerPage(page);
+}
+
 }  // namespace test
 }  // namespace app_list
diff --git a/ui/app_list/views/test/apps_grid_view_test_api.h b/ui/app_list/views/test/apps_grid_view_test_api.h
index 729c7a9..65571fe 100644
--- a/ui/app_list/views/test/apps_grid_view_test_api.h
+++ b/ui/app_list/views/test/apps_grid_view_test_api.h
@@ -7,6 +7,10 @@
 
 #include "base/macros.h"
 
+namespace gfx {
+class Rect;
+}
+
 namespace views {
 class View;
 }
@@ -26,12 +30,16 @@
 
   void LayoutToIdealBounds();
 
+  gfx::Rect GetItemTileRectAt(int row, int col) const;
+
   void SetPageFlipDelay(int page_flip_delay_in_ms);
 
   void PressItemAt(int index);
 
   bool HasPendingPageFlip() const;
 
+  int TilesPerPage(int page) const;
+
  private:
   AppsGridView* view_;
 
diff --git a/ui/aura/BUILD.gn b/ui/aura/BUILD.gn
index fad47943..4f937e6d 100644
--- a/ui/aura/BUILD.gn
+++ b/ui/aura/BUILD.gn
@@ -143,6 +143,7 @@
     "//components/discardable_memory/client",
     "//components/discardable_memory/public/interfaces",
     "//components/viz/client",
+    "//components/viz/service",
     "//gpu/ipc/client",
     "//mojo/public/cpp/system",
     "//net",
diff --git a/ui/aura/env.cc b/ui/aura/env.cc
index 0f412fb..4493d68 100644
--- a/ui/aura/env.cc
+++ b/ui/aura/env.cc
@@ -52,7 +52,8 @@
     observer.OnWillDestroyEnv();
 
 #if defined(USE_OZONE)
-  ui::OzonePlatform::Shutdown();
+  if (mode_ == Mode::LOCAL)
+    ui::OzonePlatform::Shutdown();
 #endif
 
   DCHECK_EQ(this, lazy_tls_ptr.Pointer()->Get());
diff --git a/ui/aura/local/DEPS b/ui/aura/local/DEPS
index 15433d9..c0790cb5 100644
--- a/ui/aura/local/DEPS
+++ b/ui/aura/local/DEPS
@@ -2,5 +2,6 @@
   "+cc/output",
   "+cc/scheduler",
   "+cc/surfaces",
+  "+components/viz/service/frame_sinks",
 ]
 
diff --git a/ui/aura/local/layer_tree_frame_sink_local.cc b/ui/aura/local/layer_tree_frame_sink_local.cc
index 295ae609b..c608b358 100644
--- a/ui/aura/local/layer_tree_frame_sink_local.cc
+++ b/ui/aura/local/layer_tree_frame_sink_local.cc
@@ -5,7 +5,7 @@
 #include "ui/aura/local/layer_tree_frame_sink_local.h"
 
 #include "cc/output/layer_tree_frame_sink_client.h"
-#include "cc/surfaces/compositor_frame_sink_support.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support.h"
 #include "ui/aura/client/cursor_client.h"
 #include "ui/aura/env.h"
 #include "ui/aura/window.h"
@@ -31,7 +31,7 @@
   DCHECK(!thread_checker_);
   thread_checker_ = base::MakeUnique<base::ThreadChecker>();
 
-  support_ = cc::CompositorFrameSinkSupport::Create(
+  support_ = viz::CompositorFrameSinkSupport::Create(
       this, frame_sink_manager_, frame_sink_id_, false /* is_root */,
       true /* handles_frame_sink_id_invalidation */,
       true /* needs_sync_points */);
diff --git a/ui/aura/local/layer_tree_frame_sink_local.h b/ui/aura/local/layer_tree_frame_sink_local.h
index 72daddc..eb1b9b1 100644
--- a/ui/aura/local/layer_tree_frame_sink_local.h
+++ b/ui/aura/local/layer_tree_frame_sink_local.h
@@ -9,17 +9,20 @@
 #include "base/macros.h"
 #include "cc/output/layer_tree_frame_sink.h"
 #include "cc/scheduler/begin_frame_source.h"
-#include "cc/surfaces/compositor_frame_sink_support_client.h"
 #include "components/viz/common/frame_sink_id.h"
 #include "components/viz/common/local_surface_id_allocator.h"
+#include "components/viz/service/frame_sinks/compositor_frame_sink_support_client.h"
 #include "ui/aura/window_port.h"
 #include "ui/base/property_data.h"
 
 namespace cc {
-class CompositorFrameSinkSupport;
 class FrameSinkManager;
 }  // namespace cc
 
+namespace viz {
+class CompositorFrameSinkSupport;
+}
+
 namespace aura {
 
 // cc::LayerTreeFrameSink implementation for classic aura, e.g. not mus.
@@ -27,7 +30,7 @@
 // aura::Window, and then the sink can be used for submitting frames to the
 // aura::Window's ui::Layer.
 class LayerTreeFrameSinkLocal : public cc::LayerTreeFrameSink,
-                                public cc::CompositorFrameSinkSupportClient,
+                                public viz::CompositorFrameSinkSupportClient,
                                 public cc::ExternalBeginFrameSourceClient {
  public:
   LayerTreeFrameSinkLocal(const viz::FrameSinkId& frame_sink_id,
@@ -45,7 +48,7 @@
   void SubmitCompositorFrame(cc::CompositorFrame frame) override;
   void DidNotProduceFrame(const cc::BeginFrameAck& ack) override;
 
-  // cc::CompositorFrameSinkSupportClient:
+  // viz::CompositorFrameSinkSupportClient:
   void DidReceiveCompositorFrameAck(
       const std::vector<cc::ReturnedResource>& resources) override;
   void OnBeginFrame(const cc::BeginFrameArgs& args) override;
@@ -60,7 +63,7 @@
  private:
   const viz::FrameSinkId frame_sink_id_;
   cc::FrameSinkManager* const frame_sink_manager_;
-  std::unique_ptr<cc::CompositorFrameSinkSupport> support_;
+  std::unique_ptr<viz::CompositorFrameSinkSupport> support_;
   gfx::Size surface_size_;
   float device_scale_factor_ = 0;
   viz::LocalSurfaceIdAllocator id_allocator_;
diff --git a/ui/aura/mus/window_tree_client_unittest.cc b/ui/aura/mus/window_tree_client_unittest.cc
index 2e6c8f0..7bef567 100644
--- a/ui/aura/mus/window_tree_client_unittest.cc
+++ b/ui/aura/mus/window_tree_client_unittest.cc
@@ -185,7 +185,7 @@
 // reverted if the server replied that the change failed.
 TEST_F(WindowTreeClientWmTest, SetBoundsFailedLocalSurfaceId) {
   Window window(nullptr);
-  // TOP_LEVEL_IN_WM and EMBED_IN_OWNER windows allocate cc::LocalSurfaceIds
+  // TOP_LEVEL_IN_WM and EMBED_IN_OWNER windows allocate viz::LocalSurfaceIds
   // when their sizes change.
   window.SetProperty(aura::client::kEmbedType,
                      aura::client::WindowEmbedType::EMBED_IN_OWNER);
@@ -216,7 +216,7 @@
 TEST_P(WindowTreeClientWmTestSurfaceSync,
        ClientSurfaceEmbedderOnValidEmbedding) {
   Window window(nullptr);
-  // TOP_LEVEL_IN_WM and EMBED_IN_OWNER windows allocate cc::LocalSurfaceIds
+  // TOP_LEVEL_IN_WM and EMBED_IN_OWNER windows allocate viz::LocalSurfaceIds
   // when their sizes change.
   window.SetProperty(aura::client::kEmbedType,
                      aura::client::WindowEmbedType::EMBED_IN_OWNER);
@@ -291,7 +291,7 @@
 TEST_P(WindowTreeClientWmTestSurfaceSync, SetBoundsLocalSurfaceIdChanges) {
   ASSERT_EQ(base::nullopt, window_tree()->last_local_surface_id());
   Window window(nullptr);
-  // TOP_LEVEL_IN_WM and EMBED_IN_OWNER windows allocate cc::LocalSurfaceIds
+  // TOP_LEVEL_IN_WM and EMBED_IN_OWNER windows allocate viz::LocalSurfaceIds
   // when their sizes change.
   window.SetProperty(aura::client::kEmbedType,
                      aura::client::WindowEmbedType::EMBED_IN_OWNER);
diff --git a/ui/base/accelerators/accelerator.cc b/ui/base/accelerators/accelerator.cc
index 7bbddf42..dd75623 100644
--- a/ui/base/accelerators/accelerator.cc
+++ b/ui/base/accelerators/accelerator.cc
@@ -70,6 +70,13 @@
   return flags & kModifierMask;
 }
 
+KeyEvent Accelerator::ToKeyEvent() const {
+  return KeyEvent(key_state() == Accelerator::KeyState::PRESSED
+                      ? ET_KEY_PRESSED
+                      : ET_KEY_RELEASED,
+                  key_code(), modifiers());
+}
+
 Accelerator& Accelerator::operator=(const Accelerator& accelerator) {
   if (this != &accelerator) {
     key_code_ = accelerator.key_code_;
diff --git a/ui/base/accelerators/accelerator.h b/ui/base/accelerators/accelerator.h
index 3d6b422..e6033bd 100644
--- a/ui/base/accelerators/accelerator.h
+++ b/ui/base/accelerators/accelerator.h
@@ -53,6 +53,8 @@
   // available modifier ones. This does not include EF_IS_REPEAT.
   static int MaskOutKeyEventFlags(int flags);
 
+  KeyEvent ToKeyEvent() const;
+
   Accelerator& operator=(const Accelerator& accelerator);
 
   // Define the < operator so that the KeyboardShortcut can be used as a key in
diff --git a/ui/base/cursor/cursor_loader_ozone.cc b/ui/base/cursor/cursor_loader_ozone.cc
index 5f1ba8e..b8498ef 100644
--- a/ui/base/cursor/cursor_loader_ozone.cc
+++ b/ui/base/cursor/cursor_loader_ozone.cc
@@ -12,7 +12,9 @@
 
 namespace ui {
 
-CursorLoaderOzone::CursorLoaderOzone() {}
+CursorLoaderOzone::CursorLoaderOzone() {
+  factory_ = CursorFactoryOzone::GetInstance();
+}
 
 CursorLoaderOzone::~CursorLoaderOzone() {}
 
@@ -24,8 +26,7 @@
 
   GetImageCursorBitmap(resource_id, scale(), rotation(), &hotspot, &bitmap);
 
-  cursors_[id] = CursorFactoryOzone::GetInstance()->CreateImageCursor(
-      bitmap, hotspot, scale());
+  cursors_[id] = factory_->CreateImageCursor(bitmap, hotspot, scale());
 }
 
 void CursorLoaderOzone::LoadAnimatedCursor(CursorType id,
@@ -38,15 +39,15 @@
   GetAnimatedCursorBitmaps(
       resource_id, scale(), rotation(), &hotspot, &bitmaps);
 
-  cursors_[id] = CursorFactoryOzone::GetInstance()->CreateAnimatedCursor(
-      bitmaps, hotspot, frame_delay_ms, scale());
+  cursors_[id] =
+      factory_->CreateAnimatedCursor(bitmaps, hotspot, frame_delay_ms, scale());
 }
 
 void CursorLoaderOzone::UnloadAll() {
   for (ImageCursorMap::const_iterator it = cursors_.begin();
-       it != cursors_.end();
-       ++it)
-    CursorFactoryOzone::GetInstance()->UnrefImageCursor(it->second);
+       it != cursors_.end(); ++it) {
+    factory_->UnrefImageCursor(it->second);
+  }
   cursors_.clear();
 }
 
@@ -62,7 +63,7 @@
     platform = cursor->platform();
   } else {
     // Use default cursor of this type.
-    platform = CursorFactoryOzone::GetInstance()->GetDefaultCursor(native_type);
+    platform = factory_->GetDefaultCursor(native_type);
   }
 
   cursor->SetPlatformCursor(platform);
diff --git a/ui/base/cursor/cursor_loader_ozone.h b/ui/base/cursor/cursor_loader_ozone.h
index 00a2328..acb9571 100644
--- a/ui/base/cursor/cursor_loader_ozone.h
+++ b/ui/base/cursor/cursor_loader_ozone.h
@@ -13,8 +13,12 @@
 
 namespace ui {
 
+class CursorFactoryOzone;
+
 class UI_BASE_EXPORT CursorLoaderOzone : public CursorLoader {
  public:
+  // CursorLoaderOzone will use CursorFactoryOzone corresponding to the thread
+  // it was constructed on.
   CursorLoaderOzone();
   ~CursorLoaderOzone() override;
 
@@ -33,6 +37,7 @@
   // Pointers are owned by ResourceBundle and must not be freed here.
   typedef std::map<CursorType, PlatformCursor> ImageCursorMap;
   ImageCursorMap cursors_;
+  CursorFactoryOzone* factory_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(CursorLoaderOzone);
 };
diff --git a/ui/base/cursor/image_cursors.cc b/ui/base/cursor/image_cursors.cc
index 93c25a9a..435fa5a 100644
--- a/ui/base/cursor/image_cursors.cc
+++ b/ui/base/cursor/image_cursors.cc
@@ -60,11 +60,17 @@
 
 }  // namespace
 
-ImageCursors::ImageCursors() : cursor_size_(CursorSize::kNormal) {}
+ImageCursors::ImageCursors()
+    : cursor_size_(CursorSize::kNormal), weak_ptr_factory_(this) {}
 
 ImageCursors::~ImageCursors() {
 }
 
+void ImageCursors::Initialize() {
+  if (!cursor_loader_)
+    cursor_loader_.reset(CursorLoader::Create());
+}
+
 float ImageCursors::GetScale() const {
   if (!cursor_loader_) {
     NOTREACHED();
@@ -142,4 +148,8 @@
   cursor_loader_->SetPlatformCursor(cursor);
 }
 
+base::WeakPtr<ImageCursors> ImageCursors::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 }  // namespace ui
diff --git a/ui/base/cursor/image_cursors.h b/ui/base/cursor/image_cursors.h
index 43b40e0..4d6572a 100644
--- a/ui/base/cursor/image_cursors.h
+++ b/ui/base/cursor/image_cursors.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/macros.h"
+#include "base/memory/weak_ptr.h"
 #include "base/strings/string16.h"
 #include "ui/base/cursor/cursor.h"
 #include "ui/base/ui_base_export.h"
@@ -25,6 +26,14 @@
   ImageCursors();
   ~ImageCursors();
 
+  // Creates the |cursor_loader_|. This is optional as |cursor_loader_| is
+  // lazily created if Initialize() isn't explictly called.
+  // However note that it matters which thread is used to create
+  // |cursor_loader_| (see CursorLoaderOzone,  crbug.com/741106). Thus explicit
+  // call to Initialize may be useful to ensure initialization happens on the
+  // right thread.
+  void Initialize();
+
   // Returns the scale and rotation of the currently loaded cursor.
   float GetScale() const;
   display::Display::Rotation GetRotation() const;
@@ -39,12 +48,15 @@
   // Sets the platform cursor based on the native type of |cursor|.
   void SetPlatformCursor(gfx::NativeCursor* cursor);
 
+  base::WeakPtr<ImageCursors> GetWeakPtr();
+
  private:
   // Reloads the all loaded cursors in the cursor loader.
   void ReloadCursors();
 
   std::unique_ptr<CursorLoader> cursor_loader_;
   CursorSize cursor_size_;
+  base::WeakPtrFactory<ImageCursors> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(ImageCursors);
 };
diff --git a/ui/base/resource/resource_bundle_fuchsia.cc b/ui/base/resource/resource_bundle_fuchsia.cc
new file mode 100644
index 0000000..3cf4a65
--- /dev/null
+++ b/ui/base/resource/resource_bundle_fuchsia.cc
@@ -0,0 +1,25 @@
+// 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 "ui/base/resource/resource_bundle.h"
+
+#include "base/logging.h"
+#include "base/macros.h"
+#include "ui/gfx/image/image.h"
+
+namespace ui {
+
+// TODO(fuchsia): Implement ui::ResourceBundle.
+
+void ResourceBundle::LoadCommonResources() {
+  NOTIMPLEMENTED();
+}
+
+gfx::Image& ResourceBundle::GetNativeImageNamed(int resource_id) {
+  NOTIMPLEMENTED();
+  CR_DEFINE_STATIC_LOCAL(gfx::Image, empty_image, ());
+  return empty_image;
+}
+
+}  // namespace ui
diff --git a/ui/compositor/test/DEPS b/ui/compositor/test/DEPS
index 1abcef1a..b8b2938 100644
--- a/ui/compositor/test/DEPS
+++ b/ui/compositor/test/DEPS
@@ -1,4 +1,5 @@
 include_rules = [
+  "+components/viz/service/display",
   "+components/viz/service/frame_sinks",
   "+gpu/command_buffer/client",
   "+gpu/command_buffer/common",
diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc
index 77fc0af..00f072d 100644
--- a/ui/compositor/test/in_process_context_factory.cc
+++ b/ui/compositor/test/in_process_context_factory.cc
@@ -18,13 +18,13 @@
 #include "cc/output/texture_mailbox_deleter.h"
 #include "cc/scheduler/begin_frame_source.h"
 #include "cc/scheduler/delay_based_time_source.h"
-#include "cc/surfaces/direct_layer_tree_frame_sink.h"
-#include "cc/surfaces/display.h"
-#include "cc/surfaces/display_scheduler.h"
 #include "cc/surfaces/frame_sink_manager.h"
 #include "cc/test/pixel_test_output_surface.h"
 #include "components/viz/common/local_surface_id_allocator.h"
 #include "components/viz/host/host_frame_sink_manager.h"
+#include "components/viz/service/display/display.h"
+#include "components/viz/service/display/display_scheduler.h"
+#include "components/viz/service/frame_sinks/direct_layer_tree_frame_sink.h"
 #include "gpu/command_buffer/client/context_support.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
@@ -132,7 +132,7 @@
 struct InProcessContextFactory::PerCompositorData {
   gpu::SurfaceHandle surface_handle = gpu::kNullSurfaceHandle;
   std::unique_ptr<cc::BeginFrameSource> begin_frame_source;
-  std::unique_ptr<cc::Display> display;
+  std::unique_ptr<viz::Display> display;
 };
 
 InProcessContextFactory::InProcessContextFactory(
@@ -235,11 +235,11 @@
       new cc::DelayBasedBeginFrameSource(
           base::MakeUnique<cc::DelayBasedTimeSource>(
               compositor->task_runner().get())));
-  std::unique_ptr<cc::DisplayScheduler> scheduler(new cc::DisplayScheduler(
+  auto scheduler = base::MakeUnique<viz::DisplayScheduler>(
       begin_frame_source.get(), compositor->task_runner().get(),
-      display_output_surface->capabilities().max_frames_pending));
+      display_output_surface->capabilities().max_frames_pending);
 
-  data->display = base::MakeUnique<cc::Display>(
+  data->display = base::MakeUnique<viz::Display>(
       &shared_bitmap_manager_, &gpu_memory_buffer_manager_, renderer_settings_,
       compositor->frame_sink_id(), std::move(display_output_surface),
       std::move(scheduler),
@@ -252,7 +252,7 @@
   data->begin_frame_source = std::move(begin_frame_source);
 
   auto* display = per_compositor_data_[compositor.get()]->display.get();
-  auto layer_tree_frame_sink = base::MakeUnique<cc::DirectLayerTreeFrameSink>(
+  auto layer_tree_frame_sink = base::MakeUnique<viz::DirectLayerTreeFrameSink>(
       compositor->frame_sink_id(), GetFrameSinkManager(), display,
       context_provider, shared_worker_context_provider_,
       &gpu_memory_buffer_manager_, &shared_bitmap_manager_);
diff --git a/ui/compositor/test/in_process_context_factory.h b/ui/compositor/test/in_process_context_factory.h
index 978d07e..e5f536e 100644
--- a/ui/compositor/test/in_process_context_factory.h
+++ b/ui/compositor/test/in_process_context_factory.h
@@ -9,13 +9,13 @@
 #include <memory>
 
 #include "base/macros.h"
-#include "cc/surfaces/display.h"
 #include "cc/surfaces/frame_sink_manager.h"
 #include "cc/test/test_gpu_memory_buffer_manager.h"
 #include "cc/test/test_image_factory.h"
 #include "cc/test/test_shared_bitmap_manager.h"
 #include "cc/test/test_task_graph_runner.h"
 #include "components/viz/common/frame_sink_id_allocator.h"
+#include "components/viz/service/display/display.h"
 #include "gpu/ipc/common/surface_handle.h"
 #include "ui/compositor/compositor.h"
 
diff --git a/ui/gl/BUILD.gn b/ui/gl/BUILD.gn
index f4c414d..604000e 100644
--- a/ui/gl/BUILD.gn
+++ b/ui/gl/BUILD.gn
@@ -122,6 +122,7 @@
     "gl_utils.h",
     "gl_version_info.cc",
     "gl_version_info.h",
+    "gl_workarounds.h",
     "gpu_switching_manager.cc",
     "gpu_switching_manager.h",
     "gpu_timing.cc",
diff --git a/ui/gl/gl_context.cc b/ui/gl/gl_context.cc
index 0f3b3561..80622b2f 100644
--- a/ui/gl/gl_context.cc
+++ b/ui/gl/gl_context.cc
@@ -61,6 +61,7 @@
 GLApi* GLContext::CreateGLApi(DriverGL* driver) {
   real_gl_api_ = new RealGLApi;
   real_gl_api_->Initialize(driver);
+  real_gl_api_->set_gl_workarounds(gl_workarounds_);
   return real_gl_api_;
 }
 
@@ -210,6 +211,14 @@
   }
 }
 
+void GLContext::SetGLWorkarounds(const GLWorkarounds& workarounds) {
+  DCHECK(IsCurrent(nullptr));
+  gl_workarounds_ = workarounds;
+  if (real_gl_api_) {
+    real_gl_api_->set_gl_workarounds(gl_workarounds_);
+  }
+}
+
 GLStateRestorer* GLContext::GetGLStateRestorer() {
   return state_restorer_.get();
 }
diff --git a/ui/gl/gl_context.h b/ui/gl/gl_context.h
index 0d1aa6d..ff9cfdb 100644
--- a/ui/gl/gl_context.h
+++ b/ui/gl/gl_context.h
@@ -16,6 +16,7 @@
 #include "ui/gl/gl_export.h"
 #include "ui/gl/gl_share_group.h"
 #include "ui/gl/gl_state_restorer.h"
+#include "ui/gl/gl_workarounds.h"
 #include "ui/gl/gpu_preference.h"
 
 namespace gl {
@@ -96,6 +97,9 @@
   // Creates a GPUTimingClient class which abstracts various GPU Timing exts.
   virtual scoped_refptr<GPUTimingClient> CreateGPUTimingClient() = 0;
 
+  // Set the GL workarounds.
+  void SetGLWorkarounds(const GLWorkarounds& workarounds);
+
   // Gets the GLStateRestorer for the context.
   GLStateRestorer* GetGLStateRestorer();
 
@@ -222,6 +226,8 @@
 
   std::unique_ptr<GLVersionInfo> GenerateGLVersionInfo();
 
+  GLWorkarounds gl_workarounds_;
+
   bool static_bindings_initialized_ = false;
   bool dynamic_bindings_initialized_ = false;
   std::unique_ptr<DriverGL> driver_gl_;
diff --git a/ui/gl/gl_gl_api_implementation.cc b/ui/gl/gl_gl_api_implementation.cc
index ecd5881e..bc55bfb 100644
--- a/ui/gl/gl_gl_api_implementation.cc
+++ b/ui/gl/gl_gl_api_implementation.cc
@@ -423,6 +423,21 @@
     GLApiBase::glClearFn(mask);
 }
 
+void RealGLApi::glClearColorFn(GLclampf red,
+                               GLclampf green,
+                               GLclampf blue,
+                               GLclampf alpha) {
+  if (gl_workarounds_.clear_to_zero_or_one_broken && (1 == red || 0 == red) &&
+      (1 == green || 0 == green) && (1 == blue || 0 == blue) &&
+      (1 == alpha || 0 == alpha)) {
+    if (1 == alpha)
+      alpha = 2;
+    else
+      alpha = -1;
+  }
+  GLApiBase::glClearColorFn(red, green, blue, alpha);
+}
+
 void RealGLApi::glDrawArraysFn(GLenum mode, GLint first, GLsizei count) {
   if (!g_null_draw_bindings_enabled)
     GLApiBase::glDrawArraysFn(mode, first, count);
@@ -491,6 +506,10 @@
   }
 }
 
+void RealGLApi::set_gl_workarounds(const GLWorkarounds& workarounds) {
+  gl_workarounds_ = workarounds;
+}
+
 void RealGLApi::set_version(std::unique_ptr<GLVersionInfo> version) {
   version_ = std::move(version);
 }
diff --git a/ui/gl/gl_gl_api_implementation.h b/ui/gl/gl_gl_api_implementation.h
index ba66b85..db0fcc7 100644
--- a/ui/gl/gl_gl_api_implementation.h
+++ b/ui/gl/gl_gl_api_implementation.h
@@ -11,6 +11,7 @@
 #include "base/compiler_specific.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_export.h"
+#include "ui/gl/gl_workarounds.h"
 
 namespace base {
 class CommandLine;
@@ -103,6 +104,10 @@
                                           GLsizei height) override;
 
   void glClearFn(GLbitfield mask) override;
+  void glClearColorFn(GLclampf red,
+                      GLclampf green,
+                      GLclampf blue,
+                      GLclampf alpha) override;
   void glDrawArraysFn(GLenum mode, GLint first, GLsizei count) override;
   void glDrawElementsFn(GLenum mode,
                         GLsizei count,
@@ -113,6 +118,7 @@
   void glDepthRangeFn(GLclampd z_near, GLclampd z_far) override;
 
   void InitializeFilteredExtensions();
+  void set_gl_workarounds(const GLWorkarounds& workarounds);
   void set_version(std::unique_ptr<GLVersionInfo> version);
 
  private:
@@ -121,6 +127,7 @@
   std::vector<std::string> filtered_exts_;
   std::string filtered_exts_str_;
 
+  GLWorkarounds gl_workarounds_;
   std::unique_ptr<GLVersionInfo> version_;
 
 #if DCHECK_IS_ON()
diff --git a/ui/gl/gl_image_dxgi.cc b/ui/gl/gl_image_dxgi.cc
index 750ee867..a7ab19c 100644
--- a/ui/gl/gl_image_dxgi.cc
+++ b/ui/gl/gl_image_dxgi.cc
@@ -4,77 +4,66 @@
 
 #include "ui/gl/gl_image_dxgi.h"
 
-#include <d3d11_1.h>
-
 #include "third_party/khronos/EGL/egl.h"
 #include "third_party/khronos/EGL/eglext.h"
-#include "ui/gl/gl_angle_util_win.h"
 #include "ui/gl/gl_bindings.h"
 #include "ui/gl/gl_image.h"
 #include "ui/gl/gl_surface_egl.h"
 
 namespace gl {
 
-GLImageDXGIBase::GLImageDXGIBase(const gfx::Size& size) : size_(size) {}
+GLImageDXGI::GLImageDXGI(const gfx::Size& size, EGLStreamKHR stream)
+    : size_(size), stream_(stream) {}
 
 // static
-GLImageDXGIBase* GLImageDXGIBase::FromGLImage(GLImage* image) {
+GLImageDXGI* GLImageDXGI::FromGLImage(GLImage* image) {
   if (!image || image->GetType() != Type::DXGI_IMAGE)
     return nullptr;
-  return static_cast<GLImageDXGIBase*>(image);
+  return static_cast<GLImageDXGI*>(image);
 }
 
-gfx::Size GLImageDXGIBase::GetSize() {
+gfx::Size GLImageDXGI::GetSize() {
   return size_;
 }
 
-unsigned GLImageDXGIBase::GetInternalFormat() {
+unsigned GLImageDXGI::GetInternalFormat() {
   return GL_BGRA_EXT;
 }
 
-bool GLImageDXGIBase::BindTexImage(unsigned target) {
-  return false;
-}
-
-void GLImageDXGIBase::ReleaseTexImage(unsigned target) {}
-
-bool GLImageDXGIBase::CopyTexImage(unsigned target) {
-  return false;
-}
-
-bool GLImageDXGIBase::CopyTexSubImage(unsigned target,
-                                      const gfx::Point& offset,
-                                      const gfx::Rect& rect) {
-  return false;
-}
-
-bool GLImageDXGIBase::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
-                                           int z_order,
-                                           gfx::OverlayTransform transform,
-                                           const gfx::Rect& bounds_rect,
-                                           const gfx::RectF& crop_rect) {
-  return false;
-}
-
-void GLImageDXGIBase::Flush() {}
-
-void GLImageDXGIBase::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
-                                   uint64_t process_tracing_id,
-                                   const std::string& dump_name) {}
-
-GLImage::Type GLImageDXGIBase::GetType() const {
-  return Type::DXGI_IMAGE;
-}
-
-GLImageDXGIBase::~GLImageDXGIBase() {}
-
-GLImageDXGI::GLImageDXGI(const gfx::Size& size, EGLStreamKHR stream)
-    : GLImageDXGIBase(size), stream_(stream) {}
-
 bool GLImageDXGI::BindTexImage(unsigned target) {
   return true;
 }
 
+void GLImageDXGI::ReleaseTexImage(unsigned target) {}
+
+bool GLImageDXGI::CopyTexImage(unsigned target) {
+  return false;
+}
+
+bool GLImageDXGI::CopyTexSubImage(unsigned target,
+                                  const gfx::Point& offset,
+                                  const gfx::Rect& rect) {
+  return false;
+}
+
+bool GLImageDXGI::ScheduleOverlayPlane(gfx::AcceleratedWidget widget,
+                                       int z_order,
+                                       gfx::OverlayTransform transform,
+                                       const gfx::Rect& bounds_rect,
+                                       const gfx::RectF& crop_rect) {
+  return false;
+}
+
+void GLImageDXGI::Flush() {}
+
+void GLImageDXGI::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
+                               uint64_t process_tracing_id,
+                               const std::string& dump_name) {}
+
+GLImage::Type GLImageDXGI::GetType() const {
+  return Type::DXGI_IMAGE;
+}
+
 void GLImageDXGI::SetTexture(
     const base::win::ScopedComPtr<ID3D11Texture2D>& texture,
     size_t level) {
@@ -203,34 +192,4 @@
 
 CopyingGLImageDXGI::~CopyingGLImageDXGI() {}
 
-GLImageDXGIHandle::GLImageDXGIHandle(const gfx::Size& size,
-                                     base::win::ScopedHandle handle,
-                                     uint32_t level)
-    : GLImageDXGIBase(size), handle_(std::move(handle)) {
-  level_ = level;
-}
-
-bool GLImageDXGIHandle::Initialize() {
-  base::win::ScopedComPtr<ID3D11Device> d3d11_device =
-      QueryD3D11DeviceObjectFromANGLE();
-  if (!d3d11_device)
-    return false;
-
-  base::win::ScopedComPtr<ID3D11Device1> d3d11_device1;
-  if (FAILED(d3d11_device.CopyTo(d3d11_device1.GetAddressOf())))
-    return false;
-
-  if (FAILED(d3d11_device1->OpenSharedResource1(
-          handle_.Get(), IID_PPV_ARGS(texture_.GetAddressOf())))) {
-    return false;
-  }
-  D3D11_TEXTURE2D_DESC desc;
-  texture_->GetDesc(&desc);
-  if (desc.Format != DXGI_FORMAT_NV12 || desc.ArraySize <= level_)
-    return false;
-  return true;
-}
-
-GLImageDXGIHandle::~GLImageDXGIHandle() {}
-
 }  // namespace gl
diff --git a/ui/gl/gl_image_dxgi.h b/ui/gl/gl_image_dxgi.h
index 4ea5d87..c6194610 100644
--- a/ui/gl/gl_image_dxgi.h
+++ b/ui/gl/gl_image_dxgi.h
@@ -5,7 +5,6 @@
 #include <d3d11.h>
 
 #include "base/win/scoped_comptr.h"
-#include "base/win/scoped_handle.h"
 #include "ui/gl/gl_export.h"
 #include "ui/gl/gl_image.h"
 
@@ -13,12 +12,12 @@
 
 namespace gl {
 
-class GL_EXPORT GLImageDXGIBase : public GLImage {
+class GL_EXPORT GLImageDXGI : public GLImage {
  public:
-  GLImageDXGIBase(const gfx::Size& size);
+  GLImageDXGI(const gfx::Size& size, EGLStreamKHR stream);
 
   // Safe downcast. Returns nullptr on failure.
-  static GLImageDXGIBase* FromGLImage(GLImage* image);
+  static GLImageDXGI* FromGLImage(GLImage* image);
 
   // GLImage implementation.
   gfx::Size GetSize() override;
@@ -40,34 +39,23 @@
                     const std::string& dump_name) override;
   Type GetType() const override;
 
+  void SetTexture(const base::win::ScopedComPtr<ID3D11Texture2D>& texture,
+                  size_t level);
+
   base::win::ScopedComPtr<ID3D11Texture2D> texture() { return texture_; }
   size_t level() const { return level_; }
 
  protected:
-  ~GLImageDXGIBase() override;
+  ~GLImageDXGI() override;
 
   gfx::Size size_;
 
+  EGLStreamKHR stream_;
+
   base::win::ScopedComPtr<ID3D11Texture2D> texture_;
   size_t level_ = 0;
 };
 
-class GL_EXPORT GLImageDXGI : public GLImageDXGIBase {
- public:
-  GLImageDXGI(const gfx::Size& size, EGLStreamKHR stream);
-
-  // GLImage implementation.
-  bool BindTexImage(unsigned target) override;
-
-  void SetTexture(const base::win::ScopedComPtr<ID3D11Texture2D>& texture,
-                  size_t level);
-
- protected:
-  ~GLImageDXGI() override;
-
-  EGLStreamKHR stream_;
-};
-
 // This copies to a new texture on bind.
 class GL_EXPORT CopyingGLImageDXGI : public GLImageDXGI {
  public:
@@ -98,18 +86,4 @@
   base::win::ScopedComPtr<ID3D11Texture2D> decoder_copy_texture_;
   base::win::ScopedComPtr<ID3D11VideoProcessorOutputView> output_view_;
 };
-
-class GL_EXPORT GLImageDXGIHandle : public GLImageDXGIBase {
- public:
-  GLImageDXGIHandle(const gfx::Size& size,
-                    base::win::ScopedHandle handle,
-                    uint32_t level);
-
-  bool Initialize();
-
- protected:
-  ~GLImageDXGIHandle() override;
-
-  base::win::ScopedHandle handle_;
-};
 }
diff --git a/ui/gl/gl_workarounds.h b/ui/gl/gl_workarounds.h
new file mode 100644
index 0000000..2b932142
--- /dev/null
+++ b/ui/gl/gl_workarounds.h
@@ -0,0 +1,18 @@
+// 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 UI_GL_GL_WORKAROUNDS_H_
+#define UI_GL_GL_WORKAROUNDS_H_
+
+namespace gl {
+
+struct GLWorkarounds {
+  // glClearColor does not always work on Intel 6xxx Mac drivers. See
+  // crbug.com/710443.
+  bool clear_to_zero_or_one_broken = false;
+};
+
+}  // namespace gl
+
+#endif  // UI_GL_GL_WORKAROUNDS_H_
diff --git a/ui/keyboard/content/keyboard_ui_content.cc b/ui/keyboard/content/keyboard_ui_content.cc
index 1527e6c..4a40c654 100644
--- a/ui/keyboard/content/keyboard_ui_content.cc
+++ b/ui/keyboard/content/keyboard_ui_content.cc
@@ -78,7 +78,7 @@
 
   void MoveContents(content::WebContents* source,
                     const gfx::Rect& pos) override {
-    aura::Window* keyboard = ui_->GetKeyboardWindow();
+    aura::Window* keyboard = ui_->GetContentsWindow();
     // keyboard window must have been added to keyboard container window at this
     // point. Otherwise, wrong keyboard bounds is used and may cause problem as
     // described in crbug.com/367788.
@@ -198,7 +198,7 @@
   }
 }
 
-aura::Window* KeyboardUIContent::GetKeyboardWindow() {
+aura::Window* KeyboardUIContent::GetContentsWindow() {
   if (!keyboard_contents_) {
     keyboard_contents_.reset(CreateWebContents());
     keyboard_contents_->SetDelegate(new KeyboardContentsDelegate(this));
@@ -210,7 +210,7 @@
   return keyboard_contents_->GetNativeView();
 }
 
-bool KeyboardUIContent::HasKeyboardWindow() const {
+bool KeyboardUIContent::HasContentsWindow() const {
   return !!keyboard_contents_;
 }
 
@@ -228,7 +228,7 @@
       // same as Android. Note we need to explicitly close current page as it
       // might try to resize keyboard window in javascript on a resize event.
       TRACE_EVENT0("vk", "ReloadKeyboardIfNeeded");
-      GetKeyboardWindow()->SetBounds(gfx::Rect());
+      GetContentsWindow()->SetBounds(gfx::Rect());
       keyboard_contents_->ClosePage();
       keyboard_controller()->SetKeyboardMode(FULL_WIDTH);
     }
@@ -334,10 +334,10 @@
 }
 
 bool KeyboardUIContent::ShouldEnableInsets(aura::Window* window) {
-  aura::Window* keyboard_window = GetKeyboardWindow();
-  return (keyboard_window->GetRootWindow() == window->GetRootWindow() &&
+  aura::Window* contents_window = GetContentsWindow();
+  return (contents_window->GetRootWindow() == window->GetRootWindow() &&
           keyboard::IsKeyboardOverscrollEnabled() &&
-          keyboard_window->IsVisible() &&
+          contents_window->IsVisible() &&
           keyboard_controller()->keyboard_visible());
 }
 
diff --git a/ui/keyboard/content/keyboard_ui_content.h b/ui/keyboard/content/keyboard_ui_content.h
index 9548a4d..1fdc110 100644
--- a/ui/keyboard/content/keyboard_ui_content.h
+++ b/ui/keyboard/content/keyboard_ui_content.h
@@ -63,8 +63,8 @@
   void UpdateInsetsForWindow(aura::Window* window);
 
   // Overridden from KeyboardUI:
-  aura::Window* GetKeyboardWindow() override;
-  bool HasKeyboardWindow() const override;
+  aura::Window* GetContentsWindow() override;
+  bool HasContentsWindow() const override;
   bool ShouldWindowOverscroll(aura::Window* window) const override;
   void ReloadKeyboardIfNeeded() override;
   void InitInsets(const gfx::Rect& new_bounds) override;
diff --git a/ui/keyboard/content/keyboard_ui_content_unittest.cc b/ui/keyboard/content/keyboard_ui_content_unittest.cc
index b9f295d..251cbe6 100644
--- a/ui/keyboard/content/keyboard_ui_content_unittest.cc
+++ b/ui/keyboard/content/keyboard_ui_content_unittest.cc
@@ -56,9 +56,9 @@
   content::WebContents* contents = CreateTestWebContents();
   TestKeyboardUIContent keyboard_ui(contents->GetBrowserContext(), contents);
 
-  EXPECT_FALSE(keyboard_ui.HasKeyboardWindow());
-  aura::Window* view = keyboard_ui.GetKeyboardWindow();
-  EXPECT_TRUE(keyboard_ui.HasKeyboardWindow());
+  EXPECT_FALSE(keyboard_ui.HasContentsWindow());
+  aura::Window* view = keyboard_ui.GetContentsWindow();
+  EXPECT_TRUE(keyboard_ui.HasContentsWindow());
 
   EXPECT_FALSE(view->parent());
 
diff --git a/ui/keyboard/keyboard_controller.cc b/ui/keyboard/keyboard_controller.cc
index 61cd6cb..2468e6eb 100644
--- a/ui/keyboard/keyboard_controller.cc
+++ b/ui/keyboard/keyboard_controller.cc
@@ -334,7 +334,7 @@
 void KeyboardController::NotifyKeyboardBoundsChanging(
     const gfx::Rect& new_bounds) {
   current_keyboard_bounds_ = new_bounds;
-  if (ui_->HasKeyboardWindow() && ui_->GetKeyboardWindow()->IsVisible()) {
+  if (ui_->HasContentsWindow() && ui_->GetContentsWindow()->IsVisible()) {
     for (KeyboardControllerObserver& observer : observer_list_)
       observer.OnKeyboardBoundsChanging(new_bounds);
     if (keyboard::IsKeyboardOverscrollEnabled())
@@ -441,7 +441,7 @@
 }
 
 bool KeyboardController::IsKeyboardWindowCreated() {
-  return keyboard_container_initialized() && ui_->HasKeyboardWindow();
+  return keyboard_container_initialized() && ui_->HasContentsWindow();
 }
 
 void KeyboardController::OnWindowHierarchyChanged(
@@ -469,7 +469,7 @@
     return;
   // Keep the same height when window resize. It gets called when screen
   // rotate.
-  if (!keyboard_container_initialized() || !ui_->HasKeyboardWindow())
+  if (!keyboard_container_initialized() || !ui_->HasContentsWindow())
     return;
 
   int container_height = container_->bounds().height();
@@ -491,7 +491,7 @@
 }
 
 void KeyboardController::Reload() {
-  if (ui_->HasKeyboardWindow()) {
+  if (ui_->HasContentsWindow()) {
     // A reload should never try to show virtual keyboard. If keyboard is not
     // visible before reload, it should keep invisible after reload.
     show_on_resize_ = false;
@@ -580,8 +580,7 @@
   TRACE_EVENT0("vk", "ShowKeyboardInternal");
 
   if (container_->children().empty()) {
-    // Add the WebContents window to the container if it hasn't already.
-    aura::Window* keyboard = ui_->GetKeyboardWindow();
+    aura::Window* keyboard = ui_->GetContentsWindow();
     keyboard->Show();
     container_->AddChild(keyboard);
     keyboard->set_owned_by_parent(false);
@@ -598,7 +597,7 @@
   if (keyboard_visible_) {
     return;
   } else if (!show_keyboard ||
-             ui_->GetKeyboardWindow()->bounds().height() == 0) {
+             ui_->GetContentsWindow()->bounds().height() == 0) {
     if (show_keyboard) {
       // show the keyboard once loading is complete.
       show_on_resize_ = true;
diff --git a/ui/keyboard/keyboard_controller_unittest.cc b/ui/keyboard/keyboard_controller_unittest.cc
index c3ba4cc..05af015 100644
--- a/ui/keyboard/keyboard_controller_unittest.cc
+++ b/ui/keyboard/keyboard_controller_unittest.cc
@@ -122,11 +122,11 @@
   }
 
   // Overridden from KeyboardUI:
-  bool HasKeyboardWindow() const override { return !!window_; }
+  bool HasContentsWindow() const override { return !!window_; }
   bool ShouldWindowOverscroll(aura::Window* window) const override {
     return true;
   }
-  aura::Window* GetKeyboardWindow() override {
+  aura::Window* GetContentsWindow() override {
     if (!window_) {
       window_.reset(new aura::Window(&delegate_));
       window_->Init(ui::LAYER_NOT_DRAWN);
@@ -288,9 +288,9 @@
     input_method->SetFocusedTextInputClient(client);
     if (client && client->GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE) {
       input_method->ShowImeIfNeeded();
-      if (controller_->ui()->GetKeyboardWindow()->bounds().height() == 0) {
+      if (controller_->ui()->GetContentsWindow()->bounds().height() == 0) {
         // Set initial bounds for test keyboard window.
-        controller_->ui()->GetKeyboardWindow()->SetBounds(
+        controller_->ui()->GetContentsWindow()->SetBounds(
             FullWidthKeyboardBoundsFromRootBounds(
                 root_window()->bounds(), kDefaultVirtualKeyboardHeight));
       }
@@ -302,11 +302,10 @@
   }
 
   bool ShouldEnableInsets(aura::Window* window) {
-    aura::Window* keyboard_window = controller_->ui()->GetKeyboardWindow();
-    return (keyboard_window->GetRootWindow() == window->GetRootWindow() &&
+    aura::Window* contents_window = controller_->ui()->GetContentsWindow();
+    return (contents_window->GetRootWindow() == window->GetRootWindow() &&
             keyboard::IsKeyboardOverscrollEnabled() &&
-            keyboard_window->IsVisible() &&
-            controller_->keyboard_visible());
+            contents_window->IsVisible() && controller_->keyboard_visible());
   }
 
   void ResetController() { controller_.reset(); }
@@ -333,7 +332,7 @@
 
 TEST_P(KeyboardControllerTest, KeyboardSize) {
   aura::Window* container(controller()->GetContainerWindow());
-  aura::Window* keyboard(ui()->GetKeyboardWindow());
+  aura::Window* keyboard(ui()->GetContentsWindow());
   gfx::Rect screen_bounds = root_window()->bounds();
   root_window()->AddChild(container);
   container->AddChild(keyboard);
@@ -372,7 +371,7 @@
 
 TEST_P(KeyboardControllerTest, KeyboardSizeMultiRootWindow) {
   aura::Window* container(controller()->GetContainerWindow());
-  aura::Window* keyboard(ui()->GetKeyboardWindow());
+  aura::Window* keyboard(ui()->GetContentsWindow());
   gfx::Rect screen_bounds = root_window()->bounds();
   root_window()->AddChild(container);
   container->AddChild(keyboard);
@@ -404,7 +403,7 @@
 
 TEST_P(KeyboardControllerTest, FloatingKeyboardSize) {
   aura::Window* container(controller()->GetContainerWindow());
-  aura::Window* keyboard(ui()->GetKeyboardWindow());
+  aura::Window* keyboard(ui()->GetContentsWindow());
   root_window()->AddChild(container);
   controller()->SetKeyboardMode(FLOATING);
   container->AddChild(keyboard);
@@ -516,11 +515,11 @@
   SetFocus(&no_input_client);
   // Insets should not be enabled for new windows while keyboard is in the
   // process of hiding when overscroll is enabled.
-  EXPECT_FALSE(ShouldEnableInsets(ui()->GetKeyboardWindow()));
+  EXPECT_FALSE(ShouldEnableInsets(ui()->GetContentsWindow()));
   // Cancel keyboard hide.
   SetFocus(&input_client);
   // Insets should be enabled for new windows as hide was cancelled.
-  EXPECT_TRUE(ShouldEnableInsets(ui()->GetKeyboardWindow()));
+  EXPECT_TRUE(ShouldEnableInsets(ui()->GetContentsWindow()));
 }
 
 // Verify switch to FLOATING mode will reset the overscroll or resize and when
@@ -665,9 +664,7 @@
     return controller()->GetContainerWindow();
   }
 
-  aura::Window* keyboard_window() {
-    return ui()->GetKeyboardWindow();
-  }
+  aura::Window* contents_window() { return ui()->GetContentsWindow(); }
 
  private:
   DISALLOW_COPY_AND_ASSIGN(KeyboardControllerAnimationTest);
@@ -688,7 +685,7 @@
   // Keyboard container and window should immediately become visible before
   // animation starts.
   EXPECT_TRUE(keyboard_container()->IsVisible());
-  EXPECT_TRUE(keyboard_window()->IsVisible());
+  EXPECT_TRUE(contents_window()->IsVisible());
   float show_start_opacity = layer->opacity();
   gfx::Transform transform;
   transform.Translate(0, kAnimationDistance);
@@ -697,7 +694,7 @@
 
   RunAnimationForLayer(layer);
   EXPECT_TRUE(keyboard_container()->IsVisible());
-  EXPECT_TRUE(keyboard_window()->IsVisible());
+  EXPECT_TRUE(contents_window()->IsVisible());
   float show_end_opacity = layer->opacity();
   EXPECT_LT(show_start_opacity, show_end_opacity);
   EXPECT_EQ(gfx::Transform(), layer->transform());
@@ -709,7 +706,7 @@
   controller()->HideKeyboard(KeyboardController::HIDE_REASON_AUTOMATIC);
   EXPECT_TRUE(keyboard_container()->IsVisible());
   EXPECT_TRUE(keyboard_container()->layer()->visible());
-  EXPECT_TRUE(keyboard_window()->IsVisible());
+  EXPECT_TRUE(contents_window()->IsVisible());
   float hide_start_opacity = layer->opacity();
   // KeyboardController should notify the bounds of keyboard window to its
   // observers before hide animation starts.
@@ -718,7 +715,7 @@
   RunAnimationForLayer(layer);
   EXPECT_FALSE(keyboard_container()->IsVisible());
   EXPECT_FALSE(keyboard_container()->layer()->visible());
-  EXPECT_FALSE(keyboard_window()->IsVisible());
+  EXPECT_FALSE(contents_window()->IsVisible());
   float hide_end_opacity = layer->opacity();
   EXPECT_GT(hide_start_opacity, hide_end_opacity);
   EXPECT_EQ(transform, layer->transform());
@@ -739,7 +736,7 @@
   ShowKeyboard();
   RunAnimationForLayer(layer);
   EXPECT_TRUE(keyboard_container()->IsVisible());
-  EXPECT_TRUE(keyboard_window()->IsVisible());
+  EXPECT_TRUE(contents_window()->IsVisible());
   EXPECT_EQ(1.0, layer->opacity());
   EXPECT_EQ(gfx::Transform(), layer->transform());
 }
@@ -748,7 +745,7 @@
 TEST_P(KeyboardControllerTest, FloatingKeyboardShowOnFirstTap) {
   ScopedTouchKeyboardEnabler scoped_keyboard_enabler;
   aura::Window* container(controller()->GetContainerWindow());
-  aura::Window* keyboard(ui()->GetKeyboardWindow());
+  aura::Window* keyboard(ui()->GetContentsWindow());
   root_window()->AddChild(container);
 
   controller()->SetKeyboardMode(FLOATING);
diff --git a/ui/keyboard/keyboard_ui.cc b/ui/keyboard/keyboard_ui.cc
index a0e65ac7..cd95198 100644
--- a/ui/keyboard/keyboard_ui.cc
+++ b/ui/keyboard/keyboard_ui.cc
@@ -17,10 +17,10 @@
 KeyboardUI::~KeyboardUI() {}
 
 void KeyboardUI::ShowKeyboardContainer(aura::Window* container) {
-  if (HasKeyboardWindow()) {
+  if (HasContentsWindow()) {
     {
       TRACE_EVENT0("vk", "ShowKeyboardContainerWindow");
-      GetKeyboardWindow()->Show();
+      GetContentsWindow()->Show();
     }
     {
       TRACE_EVENT0("vk", "ShowKeyboardContainer");
@@ -30,9 +30,9 @@
 }
 
 void KeyboardUI::HideKeyboardContainer(aura::Window* container) {
-  if (HasKeyboardWindow()) {
+  if (HasContentsWindow()) {
     container->Hide();
-    GetKeyboardWindow()->Hide();
+    GetContentsWindow()->Hide();
   }
 }
 
@@ -42,9 +42,9 @@
 
   TRACE_EVENT0("vk", "EnsureCaretInWorkArea");
 
-  const aura::Window* keyboard_window = GetKeyboardWindow();
+  const aura::Window* contents_window = GetContentsWindow();
   const gfx::Rect keyboard_bounds_in_screen =
-      keyboard_window->IsVisible() ? keyboard_window->GetBoundsInScreen()
+      contents_window->IsVisible() ? contents_window->GetBoundsInScreen()
                                    : gfx::Rect();
 
   // Use new virtual keyboard behavior only if the flag enabled and in
diff --git a/ui/keyboard/keyboard_ui.h b/ui/keyboard/keyboard_ui.h
index 8399c85..626f2d95 100644
--- a/ui/keyboard/keyboard_ui.h
+++ b/ui/keyboard/keyboard_ui.h
@@ -29,12 +29,13 @@
   KeyboardUI();
   virtual ~KeyboardUI();
 
-  // Gets the virtual keyboard window. May return null if the window has not yet
+  // Gets the virtual keyboard contents window i.e. the WebContents window where
+  // keyboard extensions are loaded. May return null if the window has not yet
   // been created.
-  virtual aura::Window* GetKeyboardWindow() = 0;
+  virtual aura::Window* GetContentsWindow() = 0;
 
-  // Whether the keyboard window has been created.
-  virtual bool HasKeyboardWindow() const = 0;
+  // Whether the keyboard contents window has been created.
+  virtual bool HasContentsWindow() const = 0;
 
   // Whether this window should do an overscroll to avoid occlusion by the
   // virtual keyboard. IME windows and virtual keyboard windows should always
diff --git a/ui/message_center/views/message_view.h b/ui/message_center/views/message_view.h
index 61ddf740..c45edc7 100644
--- a/ui/message_center/views/message_view.h
+++ b/ui/message_center/views/message_view.h
@@ -30,12 +30,6 @@
 class Notification;
 class MessageCenterController;
 
-// Individual notifications constants.
-const int kPaddingBetweenItems = 10;
-const int kPaddingHorizontal = 18;
-const int kWebNotificationButtonWidth = 32;
-const int kWebNotificationIconSize = 40;
-
 // An base class for a notification entry. Contains background and other
 // elements shared by derived notification views.
 class MESSAGE_CENTER_EXPORT MessageView
diff --git a/ui/ozone/public/cursor_factory_ozone.cc b/ui/ozone/public/cursor_factory_ozone.cc
index 356bd12..7efc26c 100644
--- a/ui/ozone/public/cursor_factory_ozone.cc
+++ b/ui/ozone/public/cursor_factory_ozone.cc
@@ -4,26 +4,37 @@
 
 #include "ui/ozone/public/cursor_factory_ozone.h"
 
+#include "base/lazy_instance.h"
 #include "base/logging.h"
+#include "base/threading/thread_local.h"
 
 namespace ui {
 
-// static
-CursorFactoryOzone* CursorFactoryOzone::impl_ = NULL;
+namespace {
+
+// TODO(mfomitchev): crbug.com/741106
+// Until the above bug is fixed, CursorFactoryOzone singleton needs to be
+// thread-local, because Ash creates its own instance.
+base::LazyInstance<base::ThreadLocalPointer<CursorFactoryOzone>>::Leaky
+    lazy_tls_ptr = LAZY_INSTANCE_INITIALIZER;
+
+}  // namespace
 
 CursorFactoryOzone::CursorFactoryOzone() {
-  DCHECK(!impl_) << "There should only be a single CursorFactoryOzone.";
-  impl_ = this;
+  DCHECK(!lazy_tls_ptr.Pointer()->Get())
+      << "There should only be a single CursorFactoryOzone per thread.";
+  lazy_tls_ptr.Pointer()->Set(this);
 }
 
 CursorFactoryOzone::~CursorFactoryOzone() {
-  DCHECK_EQ(impl_, this);
-  impl_ = NULL;
+  DCHECK_EQ(lazy_tls_ptr.Pointer()->Get(), this);
+  lazy_tls_ptr.Pointer()->Set(nullptr);
 }
 
 CursorFactoryOzone* CursorFactoryOzone::GetInstance() {
-  DCHECK(impl_) << "No CursorFactoryOzone implementation set.";
-  return impl_;
+  CursorFactoryOzone* result = lazy_tls_ptr.Pointer()->Get();
+  DCHECK(result) << "No CursorFactoryOzone implementation set.";
+  return result;
 }
 
 PlatformCursor CursorFactoryOzone::GetDefaultCursor(CursorType type) {
diff --git a/ui/ozone/public/cursor_factory_ozone.h b/ui/ozone/public/cursor_factory_ozone.h
index 18164baa..800595c25 100644
--- a/ui/ozone/public/cursor_factory_ozone.h
+++ b/ui/ozone/public/cursor_factory_ozone.h
@@ -23,7 +23,7 @@
   CursorFactoryOzone();
   virtual ~CursorFactoryOzone();
 
-  // Returns the singleton instance.
+  // Returns the thread-local instance.
   static CursorFactoryOzone* GetInstance();
 
   // Return the default cursor of the specified type. The types are listed in
@@ -53,9 +53,6 @@
 
   // Decrement platform image cursor refcount.
   virtual void UnrefImageCursor(PlatformCursor cursor);
-
- private:
-  static CursorFactoryOzone* impl_;  // not owned
 };
 
 }  // namespace ui
diff --git a/ui/views/bubble/bubble_dialog_delegate.cc b/ui/views/bubble/bubble_dialog_delegate.cc
index 8ce99c3..b335b5b 100644
--- a/ui/views/bubble/bubble_dialog_delegate.cc
+++ b/ui/views/bubble/bubble_dialog_delegate.cc
@@ -310,10 +310,8 @@
   // than just its title and initially focused view.  See
   // http://crbug.com/474622 for details.
   if (widget == GetWidget() && visible) {
-    ui::AXNodeData node_data;
-    GetAccessibleNodeData(&node_data);
-    if (node_data.role == ui::AX_ROLE_ALERT_DIALOG)
-      NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
+    if (GetAccessibleWindowRole() == ui::AX_ROLE_ALERT_DIALOG)
+      widget->GetRootView()->NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, true);
   }
 }
 
diff --git a/ui/views/controls/button/custom_button.cc b/ui/views/controls/button/custom_button.cc
index 4ed90e2..356d274 100644
--- a/ui/views/controls/button/custom_button.cc
+++ b/ui/views/controls/button/custom_button.cc
@@ -318,11 +318,7 @@
 
 bool CustomButton::AcceleratorPressed(const ui::Accelerator& accelerator) {
   SetState(STATE_NORMAL);
-  // TODO(beng): remove once NotifyClick takes ui::Event.
-  ui::MouseEvent synthetic_event(
-      ui::ET_MOUSE_RELEASED, gfx::Point(), gfx::Point(), ui::EventTimeForNow(),
-      ui::EF_LEFT_MOUSE_BUTTON, ui::EF_LEFT_MOUSE_BUTTON);
-  NotifyClick(synthetic_event);
+  NotifyClick(accelerator.ToKeyEvent());
   return true;
 }
 
diff --git a/ui/views/window/dialog_delegate.cc b/ui/views/window/dialog_delegate.cc
index 0acad06b..0484d5d 100644
--- a/ui/views/window/dialog_delegate.cc
+++ b/ui/views/window/dialog_delegate.cc
@@ -257,11 +257,6 @@
   return this;
 }
 
-void DialogDelegateView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
-  node_data->SetName(GetWindowTitle());
-  node_data->role = ui::AX_ROLE_DIALOG;
-}
-
 void DialogDelegateView::ViewHierarchyChanged(
     const ViewHierarchyChangedDetails& details) {
   if (details.is_add && details.child == this && GetWidget())
diff --git a/ui/views/window/dialog_delegate.h b/ui/views/window/dialog_delegate.h
index 054edfe..8d2205b 100644
--- a/ui/views/window/dialog_delegate.h
+++ b/ui/views/window/dialog_delegate.h
@@ -143,7 +143,6 @@
   View* GetContentsView() override;
 
   // Overridden from View:
-  void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
   void ViewHierarchyChanged(
       const ViewHierarchyChangedDetails& details) override;
 
diff --git a/ui/webui/resources/cr_elements/cr_dialog/compiled_resources2.gyp b/ui/webui/resources/cr_elements/cr_dialog/compiled_resources2.gyp
index 8a75ce8..abdc3e5 100644
--- a/ui/webui/resources/cr_elements/cr_dialog/compiled_resources2.gyp
+++ b/ui/webui/resources/cr_elements/cr_dialog/compiled_resources2.gyp
@@ -8,6 +8,7 @@
       'dependencies': [
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert',
         '<(DEPTH)/third_party/polymer/v1_0/components-chromium/paper-icon-button/compiled_resources2.gyp:paper-icon-button-extracted',
+        '<(EXTERNS_GYP):web_animations',
       ],
       'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
diff --git a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js
index 85dca03e..5a23b3cf 100644
--- a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js
+++ b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js
@@ -48,6 +48,10 @@
     },
   },
 
+  listeners: {
+    'pointerdown': 'onPointerdown_',
+  },
+
   /** @private {?IntersectionObserver} */
   intersectionObserver_: null,
 
@@ -198,4 +202,25 @@
     if (this.noCancel)
       e.preventDefault();
   },
+
+  /** @param {!PointerEvent} e */
+  onPointerdown_: function(e) {
+    // Only show pulse animation if user left-clicked outside of the dialog
+    // contents.
+    if (e.button != 0 || e.composedPath()[0].tagName !== 'DIALOG')
+      return;
+
+    this.animate(
+        [
+          {transform: 'scale(1)', offset: 0},
+          {transform: 'scale(1.02)', offset: 0.4},
+          {transform: 'scale(1.02)', offset: 0.6},
+          {transform: 'scale(1)', offset: 1},
+        ],
+        /** @type {!KeyframeEffectOptions} */ ({
+          duration: 180,
+          easing: 'ease-in-out',
+          iterations: 1,
+        }));
+  },
 });