diff --git a/DEPS b/DEPS
index 7ec2403..ecdcb18 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': '5ff3a5c13e579d6840e49e6ccd75b586f76582a6',
+  'skia_revision': 'bb7dd4470b7e350ce5639633eae95b8209c26d52',
   # 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': 'd01ffe7557c21151e6c8a4a4d610aa6317c96454',
+  'v8_revision': '819af83f01a01ee7d56c1e0874acefbe57f6b670',
   # 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.
@@ -64,7 +64,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling PDFium
   # and whatever else without interference from each other.
-  'pdfium_revision': 'fed39cf4a23341cf9cb5a5b432248b4247022282',
+  'pdfium_revision': 'e65d62cb8a67b776439142ee4a62cc0c3cd66f08',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling openmax_dl
   # and whatever else without interference from each other.
@@ -96,7 +96,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '6a92df3678a138bf681851fb809106324ded7ffb',
+  'catapult_revision': 'bfa19decec4a358cb3f6aa2e749009bf51cbc412',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # and whatever else without interference from each other.
@@ -406,10 +406,6 @@
     'src/third_party/cros_system_api':
       Var('chromium_git') + '/chromiumos/platform/system_api.git' + '@' + 'cc0eda812a8aaa665d4f26f5da74875284849bf6',
 
-    # Note that this is different from Android's freetype repo.
-    'src/third_party/freetype2/src':
-      Var('chromium_git') + '/chromium/src/third_party/freetype2.git' + '@' + Var('freetype_android_revision'),
-
     'src/third_party/freetype-android/src':
       Var('chromium_git') + '/chromium/src/third_party/freetype2.git' + '@' + Var('freetype_android_revision'),
 
diff --git a/android_webview/browser/parent_output_surface.cc b/android_webview/browser/parent_output_surface.cc
index bcb6f22b..fe970a3 100644
--- a/android_webview/browser/parent_output_surface.cc
+++ b/android_webview/browser/parent_output_surface.cc
@@ -32,6 +32,8 @@
   context_provider()->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0);
 }
 
+void ParentOutputSurface::SetDrawRectangle(const gfx::Rect& rect) {}
+
 void ParentOutputSurface::Reshape(const gfx::Size& size,
                                   float scale_factor,
                                   const gfx::ColorSpace& color_space,
diff --git a/android_webview/browser/parent_output_surface.h b/android_webview/browser/parent_output_surface.h
index e9eb4ca0..0b9a413 100644
--- a/android_webview/browser/parent_output_surface.h
+++ b/android_webview/browser/parent_output_surface.h
@@ -22,6 +22,7 @@
   void EnsureBackbuffer() override;
   void DiscardBackbuffer() override;
   void BindFramebuffer() override;
+  void SetDrawRectangle(const gfx::Rect& rect) override;
   void Reshape(const gfx::Size& size,
                float scale_factor,
                const gfx::ColorSpace& color_space,
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index d021615..67f0b83b 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -849,7 +849,6 @@
   deps = [
     "//ash/autoclick/common:autoclick",
     "//ash/public/cpp:ash_public_cpp",
-    "//ash/public/interfaces",
     "//ash/touch_hud",
     "//base",
     "//base:i18n",
@@ -1240,7 +1239,6 @@
     "//ash",
     "//ash/common/test:test_support",
     "//ash/public/cpp:ash_public_cpp",
-    "//ash/public/interfaces",
     "//ash/resources/vector_icons",
     "//ash/test:test_support_without_content",
     "//base",
@@ -1394,7 +1392,6 @@
     "//ash/common/strings",
     "//ash/common/test:test_support",
     "//ash/public/cpp:ash_public_cpp",
-    "//ash/public/interfaces",
     "//ash/resources",
     "//ash/resources/vector_icons",
     "//ash/test:ash_with_aura_test_support",
diff --git a/ash/autoclick/mus/BUILD.gn b/ash/autoclick/mus/BUILD.gn
index 1a8dccc..6e7481b 100644
--- a/ash/autoclick/mus/BUILD.gn
+++ b/ash/autoclick/mus/BUILD.gn
@@ -17,7 +17,6 @@
     "//ash/autoclick/common:autoclick",
     "//ash/autoclick/mus/public/interfaces",
     "//ash/public/cpp:ash_public_cpp",
-    "//ash/public/interfaces",
     "//base",
     "//mash/public/interfaces",
     "//mojo/common",
diff --git a/ash/common/system/user/user_view.cc b/ash/common/system/user/user_view.cc
index 0bd0370..f6d813c 100644
--- a/ash/common/system/user/user_view.cc
+++ b/ash/common/system/user/user_view.cc
@@ -381,12 +381,6 @@
   add_menu_option_->SetAlwaysOnTop(true);
   add_menu_option_->Show();
 
-  // We activate the entry automatically if invoked with focus.
-  if (add_user_enabled_ && user_card_view_->HasFocus()) {
-    add_user_view->GetFocusManager()->SetFocusedView(add_user_view);
-    user_card_view_->GetFocusManager()->SetFocusedView(add_user_view);
-  }
-
   // Install a listener to focus changes so that we can remove the card when
   // the focus gets changed. When called through the destruction of the bubble,
   // the FocusManager cannot be determined anymore and we remember it here.
diff --git a/ash/common/test/BUILD.gn b/ash/common/test/BUILD.gn
index 52b70b8..b4b4d37 100644
--- a/ash/common/test/BUILD.gn
+++ b/ash/common/test/BUILD.gn
@@ -31,7 +31,6 @@
   deps = [
     "//ash",
     "//ash/public/cpp:ash_public_cpp",
-    "//ash/public/interfaces",
     "//base",
     "//components/signin/core/account_id",
     "//components/user_manager",
diff --git a/ash/mus/BUILD.gn b/ash/mus/BUILD.gn
index dee2bab..ae44e0d8 100644
--- a/ash/mus/BUILD.gn
+++ b/ash/mus/BUILD.gn
@@ -88,7 +88,6 @@
   public_deps = [
     "//ash",
     "//ash/public/cpp:ash_public_cpp",
-    "//ash/public/interfaces",
     "//base",
     "//base:i18n",
     "//mash/public/interfaces",
@@ -193,6 +192,7 @@
   sources = [
     "app_launch_unittest.cc",
     "bridge/wm_shell_mus_test_api.h",
+    "screen_mus_unittest.cc",
     "test/ash_test_impl_mus.cc",
     "test/ash_test_impl_mus.h",
     "test/wm_test_base.cc",
@@ -208,7 +208,7 @@
     ":resources",
     "//ash",
     "//ash/common/test:test_support",
-    "//ash/public/interfaces",
+    "//ash/public/cpp:ash_public_cpp",
     "//ash/test:test_support_without_content",
     "//base",
     "//base/test:test_config",
diff --git a/ash/mus/screen_mus.cc b/ash/mus/screen_mus.cc
index 260bd95..e58cff9 100644
--- a/ash/mus/screen_mus.cc
+++ b/ash/mus/screen_mus.cc
@@ -4,7 +4,10 @@
 
 #include "ash/mus/screen_mus.h"
 
+#include "ash/common/wm/root_window_finder.h"
+#include "ash/common/wm_window.h"
 #include "services/ui/public/interfaces/display/display_controller.mojom.h"
+#include "ui/aura/client/screen_position_client.h"
 #include "ui/aura/env.h"
 #include "ui/aura/mus/window_tree_host_mus.h"
 #include "ui/aura/window.h"
@@ -49,4 +52,21 @@
   return aura::Env::GetInstance()->last_mouse_location();
 }
 
+bool ScreenMus::IsWindowUnderCursor(gfx::NativeWindow window) {
+  return GetWindowAtScreenPoint(GetCursorScreenPoint()) == window;
+}
+
+gfx::NativeWindow ScreenMus::GetWindowAtScreenPoint(const gfx::Point& point) {
+  aura::Window* root_window =
+      WmWindow::GetAuraWindow(wm::GetRootWindowAt(point));
+  aura::client::ScreenPositionClient* position_client =
+      aura::client::GetScreenPositionClient(root_window);
+
+  gfx::Point local_point = point;
+  if (position_client)
+    position_client->ConvertPointFromScreen(root_window, &local_point);
+
+  return root_window->GetTopWindowContainingPoint(local_point);
+}
+
 }  // namespace ash
diff --git a/ash/mus/screen_mus.h b/ash/mus/screen_mus.h
index 752a77ff..3e9e7209 100644
--- a/ash/mus/screen_mus.h
+++ b/ash/mus/screen_mus.h
@@ -34,6 +34,8 @@
   // display::ScreenBase:
   display::Display GetDisplayNearestWindow(aura::Window* window) const override;
   gfx::Point GetCursorScreenPoint() override;
+  bool IsWindowUnderCursor(gfx::NativeWindow window) override;
+  gfx::NativeWindow GetWindowAtScreenPoint(const gfx::Point& point) override;
 
   display::mojom::DisplayController* display_controller_;
 
diff --git a/ash/mus/screen_mus_unittest.cc b/ash/mus/screen_mus_unittest.cc
new file mode 100644
index 0000000..aa962b0
--- /dev/null
+++ b/ash/mus/screen_mus_unittest.cc
@@ -0,0 +1,53 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ash/mus/screen_mus.h"
+
+#include "ash/mus/window_manager.h"
+#include "ash/mus/window_manager_application.h"
+#include "ash/test/ash_test_base.h"
+#include "ash/test/ash_test_helper.h"
+#include "ui/aura/test/test_window_delegate.h"
+
+namespace ash {
+namespace test {
+
+class ScreenMusTest : public AshTestBase {
+ public:
+  ScreenMusTest() {}
+  ~ScreenMusTest() override {}
+
+  display::Screen* screen_mus() {
+    return ash_test_helper()->window_manager_app()->window_manager()->screen();
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ScreenMusTest);
+};
+
+TEST_F(ScreenMusTest, GetWindowAtScreenPoint) {
+  UpdateDisplay("1024x600");
+
+  aura::test::TestWindowDelegate test_delegate;
+  std::unique_ptr<aura::Window> w1(CreateTestWindowInShellWithDelegate(
+      &test_delegate, 23, gfx::Rect(20, 20, 50, 50)));
+
+  aura::Window* at_point =
+      screen_mus()->GetWindowAtScreenPoint(gfx::Point(25, 25));
+  EXPECT_EQ(w1.get(), at_point);
+
+  // Create a second window which overlaps with w1.
+  std::unique_ptr<aura::Window> w2(CreateTestWindowInShellWithDelegate(
+      &test_delegate, 17, gfx::Rect(25, 25, 50, 50)));
+  at_point = screen_mus()->GetWindowAtScreenPoint(gfx::Point(25, 25));
+  EXPECT_EQ(w2.get(), at_point);
+
+  // Raise w1.
+  w1->parent()->StackChildAtTop(w1.get());
+  at_point = screen_mus()->GetWindowAtScreenPoint(gfx::Point(25, 25));
+  EXPECT_EQ(w1.get(), at_point);
+}
+
+}  // namespace test
+}  // namespace ash
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn
index acf89c7b..e9d52163 100644
--- a/ash/public/cpp/BUILD.gn
+++ b/ash/public/cpp/BUILD.gn
@@ -26,4 +26,11 @@
     "//ui/aura",
     "//ui/views/mus",
   ]
+
+  public_deps = [
+    "//ash/public/interfaces:interfaces_internal",
+  ]
+
+  allow_circular_includes_from =
+      [ "//ash/public/interfaces:interfaces_internal" ]
 }
diff --git a/ash/public/interfaces/BUILD.gn b/ash/public/interfaces/BUILD.gn
index b84f896b..3657070 100644
--- a/ash/public/interfaces/BUILD.gn
+++ b/ash/public/interfaces/BUILD.gn
@@ -4,7 +4,13 @@
 
 import("//mojo/public/tools/bindings/mojom.gni")
 
-mojom("interfaces") {
+# Depend upon //ash/public/cpp:ash_public_cpp, which has a public_dep on this.
+# The two targets must be bundled together as the typemaps depend upon
+# //ash/public/cpp, and //ash/public/cpp needs to depend on this for generated
+# code (such as enums and constants).
+mojom("interfaces_internal") {
+  visibility = [ "//ash/public/cpp:ash_public_cpp" ]
+
   sources = [
     "accelerator_controller.mojom",
     "cast_config.mojom",
@@ -27,4 +33,8 @@
     "//components/signin/public/interfaces",
     "//skia/public/interfaces",
   ]
+
+  export_class_attribute = "ASH_PUBLIC_EXPORT"
+  export_define = "ASH_PUBLIC_IMPLEMENTATION=1"
+  export_header = "ash/public/cpp/ash_public_export.h"
 }
diff --git a/ash/public/interfaces/session_controller.typemap b/ash/public/interfaces/session_controller.typemap
index 1a0bbd2..4f0fde1 100644
--- a/ash/public/interfaces/session_controller.typemap
+++ b/ash/public/interfaces/session_controller.typemap
@@ -10,7 +10,6 @@
 ]
 traits_headers = [ "//ash/public/interfaces/session_controller_traits.h" ]
 public_deps = [
-  "//ash/public/cpp:ash_public_cpp",
   "//components/session_manager:base",
   "//components/user_manager",
 ]
diff --git a/ash/public/interfaces/shelf.typemap b/ash/public/interfaces/shelf.typemap
index cbf5c7f..1af3425e 100644
--- a/ash/public/interfaces/shelf.typemap
+++ b/ash/public/interfaces/shelf.typemap
@@ -5,9 +5,6 @@
 mojom = "//ash/public/interfaces/shelf.mojom"
 public_headers = [ "//ash/public/cpp/shelf_types.h" ]
 traits_headers = [ "//ash/public/interfaces/shelf_struct_traits.h" ]
-public_deps = [
-  "//ash/public/cpp:ash_public_cpp",
-]
 type_mappings = [
   "ash.mojom.ShelfAlignment=ash::ShelfAlignment",
   "ash.mojom.ShelfAutoHideBehavior=ash::ShelfAutoHideBehavior",
diff --git a/ash/public/interfaces/wallpaper.typemap b/ash/public/interfaces/wallpaper.typemap
index ce017ca..6b83004 100644
--- a/ash/public/interfaces/wallpaper.typemap
+++ b/ash/public/interfaces/wallpaper.typemap
@@ -5,7 +5,4 @@
 mojom = "//ash/public/interfaces/wallpaper.mojom"
 public_headers = [ "//components/wallpaper/wallpaper_layout.h" ]
 traits_headers = [ "//ash/public/interfaces/wallpaper_struct_traits.h" ]
-public_deps = [
-  "//ash/public/cpp:ash_public_cpp",
-]
 type_mappings = [ "ash.mojom.WallpaperLayout=wallpaper::WallpaperLayout" ]
diff --git a/ash/test/BUILD.gn b/ash/test/BUILD.gn
index baf92d4..cff635e8 100644
--- a/ash/test/BUILD.gn
+++ b/ash/test/BUILD.gn
@@ -141,7 +141,6 @@
     "//ash/common/test:test_support",
     "//ash/mus:lib",
     "//ash/public/cpp:ash_public_cpp",
-    "//ash/public/interfaces",
     "//ash/resources",
     "//base:i18n",
     "//base/test:test_support",
diff --git a/ash/touch_hud/mus/BUILD.gn b/ash/touch_hud/mus/BUILD.gn
index a91f9cc..c8e47459 100644
--- a/ash/touch_hud/mus/BUILD.gn
+++ b/ash/touch_hud/mus/BUILD.gn
@@ -15,7 +15,6 @@
 
   deps = [
     "//ash/public/cpp:ash_public_cpp",
-    "//ash/public/interfaces",
     "//ash/touch_hud",
     "//base",
     "//mash/public/interfaces",
diff --git a/base/BUILD.gn b/base/BUILD.gn
index 366aba9..8fb6be5 100644
--- a/base/BUILD.gn
+++ b/base/BUILD.gn
@@ -2125,6 +2125,7 @@
     "threading/thread_id_name_manager_unittest.cc",
     "threading/thread_local_storage_unittest.cc",
     "threading/thread_local_unittest.cc",
+    "threading/thread_task_runner_handle_unittest.cc",
     "threading/thread_unittest.cc",
     "threading/watchdog_unittest.cc",
     "threading/worker_pool_posix_unittest.cc",
diff --git a/base/i18n/rtl.cc b/base/i18n/rtl.cc
index 095d66c6d..28fa0b0 100644
--- a/base/i18n/rtl.cc
+++ b/base/i18n/rtl.cc
@@ -12,12 +12,14 @@
 #include "base/command_line.h"
 #include "base/files/file_path.h"
 #include "base/i18n/base_i18n_switches.h"
+#include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/macros.h"
 #include "base/strings/string_split.h"
 #include "base/strings/string_util.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/synchronization/lock.h"
 #include "build/build_config.h"
 #include "third_party/icu/source/common/unicode/locid.h"
 #include "third_party/icu/source/common/unicode/uchar.h"
@@ -101,6 +103,8 @@
 namespace i18n {
 
 // Represents the locale-specific ICU text direction.
+static base::LazyInstance<base::Lock>::Leaky g_icu_text_direction_lock =
+    LAZY_INSTANCE_INITIALIZER;
 static TextDirection g_icu_text_direction = UNKNOWN_DIRECTION;
 
 // Convert the ICU default locale to a string.
@@ -150,7 +154,10 @@
   // presence of actual locale data). However,
   // it does not hurt to have it as a sanity check.
   DCHECK(U_SUCCESS(error_code));
-  g_icu_text_direction = UNKNOWN_DIRECTION;
+  {
+    base::AutoLock lock(g_icu_text_direction_lock.Get());
+    g_icu_text_direction = UNKNOWN_DIRECTION;
+  }
 }
 
 bool IsRTL() {
@@ -158,6 +165,7 @@
 }
 
 bool ICUIsRTL() {
+  base::AutoLock lock(g_icu_text_direction_lock.Get());
   if (g_icu_text_direction == UNKNOWN_DIRECTION) {
     const icu::Locale& locale = icu::Locale::getDefault();
     g_icu_text_direction = GetTextDirectionForLocaleInStartUp(locale.getName());
diff --git a/base/test/test_mock_time_task_runner.cc b/base/test/test_mock_time_task_runner.cc
index eaaceb6..5d08976 100644
--- a/base/test/test_mock_time_task_runner.cc
+++ b/base/test/test_mock_time_task_runner.cc
@@ -8,6 +8,7 @@
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/memory/ref_counted.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "base/time/clock.h"
 #include "base/time/tick_clock.h"
 
@@ -120,6 +121,16 @@
 
 // TestMockTimeTaskRunner -----------------------------------------------------
 
+// TODO(gab): This should also set the SequenceToken for the current thread.
+// Ref. TestMockTimeTaskRunner::RunsTasksOnCurrentThread().
+TestMockTimeTaskRunner::ScopedContext::ScopedContext(
+    scoped_refptr<TestMockTimeTaskRunner> scope)
+    : on_destroy_(ThreadTaskRunnerHandle::OverrideForTesting(scope)) {
+  scope->RunUntilIdle();
+}
+
+TestMockTimeTaskRunner::ScopedContext::~ScopedContext() = default;
+
 bool TestMockTimeTaskRunner::TemporalOrder::operator()(
     const TestOrderedPendingTask& first_task,
     const TestOrderedPendingTask& second_task) const {
@@ -213,6 +224,9 @@
                         : tasks_.top().GetTimeToRun() - now_ticks_;
 }
 
+// TODO(gab): Combine |thread_checker_| with a SequenceToken to differentiate
+// between tasks running in the scope of this TestMockTimeTaskRunner and other
+// task runners sharing this thread. http://crbug.com/631186
 bool TestMockTimeTaskRunner::RunsTasksOnCurrentThread() const {
   return thread_checker_.CalledOnValidThread();
 }
@@ -253,6 +267,15 @@
 
 void TestMockTimeTaskRunner::ProcessAllTasksNoLaterThan(TimeDelta max_delta) {
   DCHECK_GE(max_delta, TimeDelta());
+
+  // Multiple test task runners can share the same thread for determinism in
+  // unit tests. Make sure this TestMockTimeTaskRunner's tasks run in its scope.
+  ScopedClosureRunner undo_override;
+  if (!ThreadTaskRunnerHandle::IsSet() ||
+      ThreadTaskRunnerHandle::Get() != this) {
+    undo_override = ThreadTaskRunnerHandle::OverrideForTesting(this);
+  }
+
   const TimeTicks original_now_ticks = now_ticks_;
   while (!IsElapsingStopped()) {
     OnBeforeSelectingTask();
diff --git a/base/test/test_mock_time_task_runner.h b/base/test/test_mock_time_task_runner.h
index bf945a0..54ebbdb 100644
--- a/base/test/test_mock_time_task_runner.h
+++ b/base/test/test_mock_time_task_runner.h
@@ -12,6 +12,7 @@
 #include <queue>
 #include <vector>
 
+#include "base/callback_helpers.h"
 #include "base/macros.h"
 #include "base/single_thread_task_runner.h"
 #include "base/synchronization/lock.h"
@@ -47,6 +48,53 @@
 // that it supports running delayed tasks in the correct temporal order.
 class TestMockTimeTaskRunner : public SingleThreadTaskRunner {
  public:
+  // Everything that is executed in the scope of a ScopedContext will behave as
+  // though it ran under |scope| (i.e. ThreadTaskRunnerHandle,
+  // RunsTasksOnCurrentThread, etc.). This allows the test body to be all in one
+  // block when multiple TestMockTimeTaskRunners share the main thread. For
+  // example:
+  //
+  //   class ExampleFixture {
+  //    protected:
+  //     DoBarOnFoo() {
+  //       DCHECK(foo_task_runner_->RunsOnCurrentThread());
+  //       EXPECT_EQ(foo_task_runner_, ThreadTaskRunnerHandle::Get());
+  //       DoBar();
+  //     }
+  //
+  //     // Mock main task runner.
+  //     base::MessageLoop message_loop_;
+  //     base::ScopedMockTimeMessageLoopTaskRunner main_task_runner_;
+  //
+  //     // Mock foo task runner.
+  //     scoped_refptr<TestMockTimeTaskRunner> foo_task_runner_ =
+  //         new TestMockTimeTaskRunner();
+  //   };
+  //
+  //   TEST_F(ExampleFixture, DoBarOnFoo) {
+  //     DoThingsOnMain();
+  //     {
+  //       TestMockTimeTaskRunner::ScopedContext scoped_context(
+  //           foo_task_runner_.get());
+  //       DoBarOnFoo();
+  //     }
+  //     DoMoreThingsOnMain();
+  //   }
+  //
+  class ScopedContext {
+   public:
+    // Note: |scope| is ran until idle as part of this constructor to ensure
+    // that anything which runs in the underlying scope runs after any already
+    // pending tasks (the contrary would break the SequencedTraskRunner
+    // contract).
+    explicit ScopedContext(scoped_refptr<TestMockTimeTaskRunner> scope);
+    ~ScopedContext();
+
+   private:
+    ScopedClosureRunner on_destroy_;
+    DISALLOW_COPY_AND_ASSIGN(ScopedContext);
+  };
+
   // Constructs an instance whose virtual time will start at the Unix epoch, and
   // whose time ticks will start at zero.
   TestMockTimeTaskRunner();
diff --git a/base/test/test_simple_task_runner.cc b/base/test/test_simple_task_runner.cc
index e777918..090a72e 100644
--- a/base/test/test_simple_task_runner.cc
+++ b/base/test/test_simple_task_runner.cc
@@ -5,6 +5,8 @@
 #include "base/test/test_simple_task_runner.h"
 
 #include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "base/threading/thread_task_runner_handle.h"
 
 namespace base {
 
@@ -34,6 +36,9 @@
   return true;
 }
 
+// TODO(gab): Use SequenceToken here to differentiate between tasks running in
+// the scope of this TestSimpleTaskRunner and other task runners sharing this
+// thread. http://crbug.com/631186
 bool TestSimpleTaskRunner::RunsTasksOnCurrentThread() const {
   return thread_ref_ == PlatformThread::CurrentRef();
 }
@@ -78,6 +83,14 @@
     tasks_to_run.swap(pending_tasks_);
   }
 
+  // Multiple test task runners can share the same thread for determinism in
+  // unit tests. Make sure this TestSimpleTaskRunner's tasks run in its scope.
+  ScopedClosureRunner undo_override;
+  if (!ThreadTaskRunnerHandle::IsSet() ||
+      ThreadTaskRunnerHandle::Get() != this) {
+    undo_override = ThreadTaskRunnerHandle::OverrideForTesting(this);
+  }
+
   for (auto& task : tasks_to_run)
     std::move(task.task).Run();
 }
diff --git a/base/threading/post_task_and_reply_impl_unittest.cc b/base/threading/post_task_and_reply_impl_unittest.cc
index 8c6faaf8..13d5cc98 100644
--- a/base/threading/post_task_and_reply_impl_unittest.cc
+++ b/base/threading/post_task_and_reply_impl_unittest.cc
@@ -9,7 +9,7 @@
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/test/test_simple_task_runner.h"
-#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -74,7 +74,7 @@
 TEST(PostTaskAndReplyImplTest, PostTaskAndReply) {
   scoped_refptr<TestSimpleTaskRunner> post_runner(new TestSimpleTaskRunner);
   scoped_refptr<TestSimpleTaskRunner> reply_runner(new TestSimpleTaskRunner);
-  SequencedTaskRunnerHandle sequenced_task_runner_handle(reply_runner);
+  ThreadTaskRunnerHandle task_runner_handle(reply_runner);
 
   testing::StrictMock<MockObject> mock_object;
   bool delete_flag = false;
diff --git a/base/threading/thread_task_runner_handle.cc b/base/threading/thread_task_runner_handle.cc
index 190e18f..d71cabb 100644
--- a/base/threading/thread_task_runner_handle.cc
+++ b/base/threading/thread_task_runner_handle.cc
@@ -6,8 +6,10 @@
 
 #include <utility>
 
+#include "base/bind.h"
 #include "base/lazy_instance.h"
 #include "base/logging.h"
+#include "base/memory/ptr_util.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "base/threading/thread_local.h"
 
@@ -32,6 +34,50 @@
   return !!lazy_tls_ptr.Pointer()->Get();
 }
 
+// static
+ScopedClosureRunner ThreadTaskRunnerHandle::OverrideForTesting(
+    scoped_refptr<SingleThreadTaskRunner> overriding_task_runner) {
+  // OverrideForTesting() is not compatible with a SequencedTaskRunnerHandle
+  // being set (but SequencedTaskRunnerHandle::IsSet() includes
+  // ThreadTaskRunnerHandle::IsSet() so that's discounted as the only valid
+  // excuse for it to be true). Sadly this means that tests that merely need a
+  // SequencedTaskRunnerHandle on their main thread can be forced to use a
+  // ThreadTaskRunnerHandle if they're also using test task runners (that
+  // OverrideForTesting() when running their tasks from said main thread). To
+  // solve this: sequence_task_runner_handle.cc and thread_task_runner_handle.cc
+  // would have to be merged into a single impl file and share TLS state. This
+  // was deemed unecessary for now as most tests should use higher level
+  // constructs and not have to instantiate task runner handles on their own.
+  DCHECK(!SequencedTaskRunnerHandle::IsSet() || IsSet());
+
+  if (!IsSet()) {
+    std::unique_ptr<ThreadTaskRunnerHandle> top_level_ttrh =
+        MakeUnique<ThreadTaskRunnerHandle>(std::move(overriding_task_runner));
+    return ScopedClosureRunner(base::Bind(
+        [](std::unique_ptr<ThreadTaskRunnerHandle> ttrh_to_release) {},
+        base::Passed(&top_level_ttrh)));
+  }
+
+  ThreadTaskRunnerHandle* ttrh = lazy_tls_ptr.Pointer()->Get();
+  // Swap the two (and below bind |overriding_task_runner|, which is now the
+  // previous one, as the |task_runner_to_restore|).
+  ttrh->task_runner_.swap(overriding_task_runner);
+
+  return ScopedClosureRunner(base::Bind(
+      [](scoped_refptr<SingleThreadTaskRunner> task_runner_to_restore,
+         SingleThreadTaskRunner* expected_task_runner_before_restore) {
+        ThreadTaskRunnerHandle* ttrh = lazy_tls_ptr.Pointer()->Get();
+
+        DCHECK_EQ(expected_task_runner_before_restore, ttrh->task_runner_.get())
+            << "Nested overrides must expire their ScopedClosureRunners "
+               "in LIFO order.";
+
+        ttrh->task_runner_.swap(task_runner_to_restore);
+      },
+      base::Passed(&overriding_task_runner),
+      base::Unretained(ttrh->task_runner_.get())));
+}
+
 ThreadTaskRunnerHandle::ThreadTaskRunnerHandle(
     scoped_refptr<SingleThreadTaskRunner> task_runner)
     : task_runner_(std::move(task_runner)) {
diff --git a/base/threading/thread_task_runner_handle.h b/base/threading/thread_task_runner_handle.h
index c8e5893..7ae85e6 100644
--- a/base/threading/thread_task_runner_handle.h
+++ b/base/threading/thread_task_runner_handle.h
@@ -6,6 +6,7 @@
 #define BASE_THREADING_THREAD_TASK_RUNNER_HANDLE_H_
 
 #include "base/base_export.h"
+#include "base/callback_helpers.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
@@ -26,6 +27,17 @@
   // the current thread.
   static bool IsSet();
 
+  // Overrides ThreadTaskRunnerHandle::Get()'s |task_runner_| to point at
+  // |overriding_task_runner| until the returned ScopedClosureRunner goes out of
+  // scope (instantiates a ThreadTaskRunnerHandle for that scope if |!IsSet()|).
+  // Nested overrides are allowed but callers must ensure the
+  // ScopedClosureRunners expire in LIFO (stack) order. Note: nesting
+  // ThreadTaskRunnerHandles isn't generally desired but it's useful in unit
+  // tests where multiple task runners can share the main thread for simplicity
+  // and determinism.
+  static ScopedClosureRunner OverrideForTesting(
+      scoped_refptr<SingleThreadTaskRunner> overriding_task_runner);
+
   // Binds |task_runner| to the current thread. |task_runner| must belong
   // to the current thread for this to succeed.
   explicit ThreadTaskRunnerHandle(
diff --git a/base/threading/thread_task_runner_handle_unittest.cc b/base/threading/thread_task_runner_handle_unittest.cc
new file mode 100644
index 0000000..1aa02d1
--- /dev/null
+++ b/base/threading/thread_task_runner_handle_unittest.cc
@@ -0,0 +1,122 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/threading/thread_task_runner_handle.h"
+
+#include "base/memory/ref_counted.h"
+#include "base/test/gtest_util.h"
+#include "base/test/test_simple_task_runner.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace base {
+
+TEST(ThreadTaskRunnerHandleTest, Basic) {
+  scoped_refptr<SingleThreadTaskRunner> task_runner(new TestSimpleTaskRunner);
+
+  EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet());
+  {
+    ThreadTaskRunnerHandle ttrh1(task_runner);
+    EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet());
+    EXPECT_EQ(task_runner, ThreadTaskRunnerHandle::Get());
+  }
+  EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet());
+}
+
+TEST(ThreadTaskRunnerHandleTest, DeathOnImplicitOverride) {
+  scoped_refptr<SingleThreadTaskRunner> task_runner(new TestSimpleTaskRunner);
+  scoped_refptr<SingleThreadTaskRunner> overidding_task_runner(
+      new TestSimpleTaskRunner);
+
+  ThreadTaskRunnerHandle ttrh(task_runner);
+  EXPECT_DCHECK_DEATH(
+      { ThreadTaskRunnerHandle overriding_ttrh(overidding_task_runner); });
+}
+
+TEST(ThreadTaskRunnerHandleTest, OverrideForTestingExistingTTRH) {
+  scoped_refptr<SingleThreadTaskRunner> task_runner_1(new TestSimpleTaskRunner);
+  scoped_refptr<SingleThreadTaskRunner> task_runner_2(new TestSimpleTaskRunner);
+  scoped_refptr<SingleThreadTaskRunner> task_runner_3(new TestSimpleTaskRunner);
+  scoped_refptr<SingleThreadTaskRunner> task_runner_4(new TestSimpleTaskRunner);
+
+  EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet());
+  {
+    // TTRH in place prior to override.
+    ThreadTaskRunnerHandle ttrh1(task_runner_1);
+    EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet());
+    EXPECT_EQ(task_runner_1, ThreadTaskRunnerHandle::Get());
+
+    {
+      // Override.
+      ScopedClosureRunner undo_override_2 =
+          ThreadTaskRunnerHandle::OverrideForTesting(task_runner_2);
+      EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet());
+      EXPECT_EQ(task_runner_2, ThreadTaskRunnerHandle::Get());
+
+      {
+        // Nested override.
+        ScopedClosureRunner undo_override_3 =
+            ThreadTaskRunnerHandle::OverrideForTesting(task_runner_3);
+        EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet());
+        EXPECT_EQ(task_runner_3, ThreadTaskRunnerHandle::Get());
+      }
+
+      // Back to single override.
+      EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet());
+      EXPECT_EQ(task_runner_2, ThreadTaskRunnerHandle::Get());
+
+      {
+        // Backup to double override with another TTRH.
+        ScopedClosureRunner undo_override_4 =
+            ThreadTaskRunnerHandle::OverrideForTesting(task_runner_4);
+        EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet());
+        EXPECT_EQ(task_runner_4, ThreadTaskRunnerHandle::Get());
+      }
+    }
+
+    // Back to simple TTRH.
+    EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet());
+    EXPECT_EQ(task_runner_1, ThreadTaskRunnerHandle::Get());
+  }
+  EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet());
+}
+
+TEST(ThreadTaskRunnerHandleTest, OverrideForTestingNoExistingTTRH) {
+  scoped_refptr<SingleThreadTaskRunner> task_runner_1(new TestSimpleTaskRunner);
+  scoped_refptr<SingleThreadTaskRunner> task_runner_2(new TestSimpleTaskRunner);
+
+  EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet());
+  {
+    // Override with no TTRH in place.
+    ScopedClosureRunner undo_override_1 =
+        ThreadTaskRunnerHandle::OverrideForTesting(task_runner_1);
+    EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet());
+    EXPECT_EQ(task_runner_1, ThreadTaskRunnerHandle::Get());
+
+    {
+      // Nested override works the same.
+      ScopedClosureRunner undo_override_2 =
+          ThreadTaskRunnerHandle::OverrideForTesting(task_runner_2);
+      EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet());
+      EXPECT_EQ(task_runner_2, ThreadTaskRunnerHandle::Get());
+    }
+
+    // Back to single override.
+    EXPECT_TRUE(ThreadTaskRunnerHandle::IsSet());
+    EXPECT_EQ(task_runner_1, ThreadTaskRunnerHandle::Get());
+  }
+  EXPECT_FALSE(ThreadTaskRunnerHandle::IsSet());
+}
+
+TEST(ThreadTaskRunnerHandleTest, DeathOnTTRHOverOverride) {
+  scoped_refptr<SingleThreadTaskRunner> task_runner(new TestSimpleTaskRunner);
+  scoped_refptr<SingleThreadTaskRunner> overidding_task_runner(
+      new TestSimpleTaskRunner);
+
+  ScopedClosureRunner undo_override =
+      ThreadTaskRunnerHandle::OverrideForTesting(task_runner);
+  EXPECT_DCHECK_DEATH(
+      { ThreadTaskRunnerHandle overriding_ttrh(overidding_task_runner); });
+}
+
+}  // namespace base
diff --git a/breakpad/symupload.exe b/breakpad/symupload.exe
index b06a0ce..7e0e9fb3 100755
--- a/breakpad/symupload.exe
+++ b/breakpad/symupload.exe
Binary files differ
diff --git a/build/android/pylib/utils/device_dependencies.py b/build/android/pylib/utils/device_dependencies.py
index dc9b01f..9046122 100644
--- a/build/android/pylib/utils/device_dependencies.py
+++ b/build/android/pylib/utils/device_dependencies.py
@@ -14,6 +14,7 @@
   re.compile(r'.*\.so'),  # Libraries packed into .apk.
   re.compile(r'.*Mojo.*manifest\.json'),  # Some source_set()s pull these in.
   re.compile(r'.*\.py'),  # Some test_support targets include python deps.
+  re.compile(r'.*\.stamp'),  # Stamp files should never be included.
 
   # Some test_support targets include python deps.
   re.compile(r'.*\.mojom\.js'),
diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh
index 32db1424..7f19b7f 100755
--- a/build/install-build-deps.sh
+++ b/build/install-build-deps.sh
@@ -136,19 +136,76 @@
 chromeos_dev_list="libbluetooth-dev libxkbcommon-dev realpath"
 
 # Packages needed for development
-dev_list="bison cdbs curl dpkg-dev elfutils devscripts fakeroot
-          flex fonts-ipafont fonts-thai-tlwg g++ git-core git-svn gperf
-          libasound2-dev libbrlapi-dev libav-tools libbz2-dev libcairo2-dev
-          libcap-dev libcups2-dev libcurl4-gnutls-dev libdrm-dev libelf-dev
-          libffi-dev libgconf2-dev libglib2.0-dev libglu1-mesa-dev
-          libgnome-keyring-dev libgtk2.0-dev libkrb5-dev libnspr4-dev
-          libnss3-dev libpam0g-dev libpci-dev libpulse-dev libsctp-dev
-          libspeechd-dev libsqlite3-dev libssl-dev libudev-dev libwww-perl
-          libxslt1-dev libxss-dev libxt-dev libxtst-dev openbox patch perl
-          pkg-config python python-cherrypy3 python-crypto python-dev
-          python-numpy python-opencv python-openssl python-psutil python-yaml
-          rpm ruby subversion ttf-dejavu-core wdiff xcompmgr zip
-          $chromeos_dev_list"
+dev_list="\
+  bison
+  cdbs
+  curl
+  dpkg-dev
+  elfutils
+  devscripts
+  fakeroot
+  flex
+  fonts-ipafont
+  fonts-thai-tlwg
+  g++
+  git-core
+  git-svn
+  gperf
+  libasound2-dev
+  libbrlapi-dev
+  libav-tools
+  libbz2-dev
+  libcairo2-dev
+  libcap-dev
+  libcups2-dev
+  libcurl4-gnutls-dev
+  libdrm-dev
+  libelf-dev
+  libffi-dev
+  libgconf2-dev
+  libglib2.0-dev
+  libglu1-mesa-dev
+  libgnome-keyring-dev
+  libgtk2.0-dev
+  libgtk-3-dev
+  libkrb5-dev
+  libnspr4-dev
+  libnss3-dev
+  libpam0g-dev
+  libpci-dev
+  libpulse-dev
+  libsctp-dev
+  libspeechd-dev
+  libsqlite3-dev
+  libssl-dev
+  libudev-dev
+  libwww-perl
+  libxslt1-dev
+  libxss-dev
+  libxt-dev
+  libxtst-dev
+  openbox
+  patch
+  perl
+  pkg-config
+  python
+  python-cherrypy3
+  python-crypto
+  python-dev
+  python-numpy
+  python-opencv
+  python-openssl
+  python-psutil
+  python-yaml
+  rpm
+  ruby
+  subversion
+  ttf-dejavu-core
+  wdiff
+  xcompmgr
+  zip
+  $chromeos_dev_list
+"
 
 # 64-bit systems need a minimum set of 32-bit compat packages for the pre-built
 # NaCl binaries.
@@ -160,22 +217,79 @@
 chromeos_lib_list="libpulse0 libbz2-1.0"
 
 # Full list of required run-time libraries
-lib_list="libatk1.0-0 libc6 libasound2 libcairo2 libcap2 libcups2 libexpat1
-          libffi6 libfontconfig1 libfreetype6 libglib2.0-0 libgnome-keyring0
-          libgtk2.0-0 libpam0g libpango1.0-0 libpci3 libpcre3 libpixman-1-0
-          libspeechd2 libstdc++6 libsqlite3-0 libx11-6 libx11-xcb1
-          libxau6 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxdmcp6
-          libxext6 libxfixes3 libxi6 libxinerama1 libxrandr2 libxrender1
-          libxtst6 zlib1g $chromeos_lib_list"
+lib_list="\
+  libatk1.0-0
+  libc6
+  libasound2
+  libcairo2
+  libcap2
+  libcups2
+  libexpat1
+  libffi6
+  libfontconfig1
+  libfreetype6
+  libglib2.0-0
+  libgnome-keyring0
+  libgtk2.0-0
+  libgtk-3-0
+  libpam0g
+  libpango1.0-0
+  libpci3
+  libpcre3
+  libpixman-1-0
+  libspeechd2
+  libstdc++6
+  libsqlite3-0
+  libx11-6
+  libx11-xcb1
+  libxau6
+  libxcb1
+  libxcomposite1
+  libxcursor1
+  libxdamage1
+  libxdmcp6
+  libxext6
+  libxfixes3
+  libxi6
+  libxinerama1
+  libxrandr2
+  libxrender1
+  libxtst6
+  zlib1g
+  $chromeos_lib_list
+"
 
 # Debugging symbols for all of the run-time libraries
-dbg_list="libatk1.0-dbg libc6-dbg libcairo2-dbg libffi6-dbg libfontconfig1-dbg
-          libglib2.0-0-dbg libgtk2.0-0-dbg libpango1.0-0-dbg libpcre3-dbg
-          libpixman-1-0-dbg libsqlite3-0-dbg libx11-6-dbg libx11-xcb1-dbg
-          libxau6-dbg libxcb1-dbg libxcomposite1-dbg libxcursor1-dbg
-          libxdamage1-dbg libxdmcp6-dbg libxext6-dbg libxfixes3-dbg libxi6-dbg
-          libxinerama1-dbg libxrandr2-dbg libxrender1-dbg libxtst6-dbg
-          zlib1g-dbg"
+dbg_list="\
+  libatk1.0-dbg
+  libc6-dbg
+  libcairo2-dbg
+  libffi6-dbg
+  libfontconfig1-dbg
+  libglib2.0-0-dbg
+  libgtk2.0-0-dbg
+  libgtk-3-0-dbg
+  libpango1.0-0-dbg
+  libpcre3-dbg
+  libpixman-1-0-dbg
+  libsqlite3-0-dbg
+  libx11-6-dbg
+  libx11-xcb1-dbg
+  libxau6-dbg
+  libxcb1-dbg
+  libxcomposite1-dbg
+  libxcursor1-dbg
+  libxdamage1-dbg
+  libxdmcp6-dbg
+  libxext6-dbg
+  libxfixes3-dbg
+  libxi6-dbg
+  libxinerama1-dbg
+  libxrandr2-dbg
+  libxrender1-dbg
+  libxtst6-dbg
+  zlib1g-dbg
+"
 
 # Find the proper version of libstdc++6-4.x-dbg.
 if [ "x$lsb_release" = "xprecise" ]; then
@@ -251,14 +365,37 @@
 
 # Packages to build NaCl, its toolchains, and its ports.
 naclports_list="ant autoconf bison cmake gawk intltool xutils-dev xsltproc"
-nacl_list="g++-mingw-w64-i686 lib32z1-dev
-           libasound2:i386 libcap2:i386 libelf-dev:i386 libfontconfig1:i386
-           libgconf-2-4:i386 libglib2.0-0:i386 libgpm2:i386 libgtk2.0-0:i386
-           libncurses5:i386 lib32ncurses5-dev libnss3:i386 libpango1.0-0:i386
-           libssl1.0.0:i386 libtinfo-dev libtinfo-dev:i386 libtool
-           libxcomposite1:i386 libxcursor1:i386 libxdamage1:i386 libxi6:i386
-           libxrandr2:i386 libxss1:i386 libxtst6:i386 texinfo xvfb
-           ${naclports_list}"
+nacl_list="\
+  g++-mingw-w64-i686
+  lib32z1-dev
+  libasound2:i386
+  libcap2:i386
+  libelf-dev:i386
+  libfontconfig1:i386
+  libgconf-2-4:i386
+  libglib2.0-0:i386
+  libgpm2:i386
+  libgtk2.0-0:i386
+  libgtk-3-0:i386
+  libncurses5:i386
+  lib32ncurses5-dev
+  libnss3:i386
+  libpango1.0-0:i386
+  libssl1.0.0:i386
+  libtinfo-dev
+  libtinfo-dev:i386
+  libtool
+  libxcomposite1:i386
+  libxcursor1:i386
+  libxdamage1:i386
+  libxi6:i386
+  libxrandr2:i386
+  libxss1:i386
+  libxtst6:i386
+  texinfo
+  xvfb
+  ${naclports_list}
+"
 
 # Find the proper version of packages that depend on mesa. Only one -lts variant
 # of mesa can be installed and everything that depends on it must match.
diff --git a/cc/output/direct_renderer.cc b/cc/output/direct_renderer.cc
index c059196..77ff41f 100644
--- a/cc/output/direct_renderer.cc
+++ b/cc/output/direct_renderer.cc
@@ -84,9 +84,12 @@
 
   use_partial_swap_ = settings_->partial_swap_enabled && CanPartialSwap();
   allow_empty_swap_ = use_partial_swap_;
-  if (context_provider &&
-      context_provider->ContextCapabilities().commit_overlay_planes)
-    allow_empty_swap_ = true;
+  if (context_provider) {
+    if (context_provider->ContextCapabilities().commit_overlay_planes)
+      allow_empty_swap_ = true;
+    if (context_provider->ContextCapabilities().set_draw_rectangle)
+      use_set_draw_rectangle_ = true;
+  }
 
   initialized_ = true;
 }
@@ -511,10 +514,16 @@
         current_frame()->ComputeScissorRectForRenderPass());
   }
 
-  bool render_pass_is_clipped =
-      !render_pass_scissor_in_draw_space.Contains(surface_rect_in_draw_space);
   bool is_root_render_pass =
       current_frame()->current_render_pass == current_frame()->root_render_pass;
+
+  // The SetDrawRectangleCHROMIUM spec requires that the scissor bit is always
+  // set on the root framebuffer or else the rendering may modify something
+  // outside the damage rectangle, even if the damage rectangle is the size of
+  // the full backbuffer.
+  bool render_pass_is_clipped =
+      (use_set_draw_rectangle_ && is_root_render_pass) ||
+      !render_pass_scissor_in_draw_space.Contains(surface_rect_in_draw_space);
   bool has_external_stencil_test =
       is_root_render_pass && output_surface_->HasExternalStencilTest();
   bool should_clear_surface =
@@ -583,9 +592,12 @@
 
 bool DirectRenderer::UseRenderPass(const RenderPass* render_pass) {
   current_frame()->current_render_pass = render_pass;
-  current_frame()->current_texture = NULL;
+  current_frame()->current_texture = nullptr;
   if (render_pass == current_frame()->root_render_pass) {
     BindFramebufferToOutputSurface();
+
+    if (use_set_draw_rectangle_)
+      output_surface_->SetDrawRectangle(current_frame()->root_damage_rect);
     InitializeViewport(current_frame(), render_pass->output_rect,
                        gfx::Rect(current_frame()->device_viewport_size),
                        current_frame()->device_viewport_size);
diff --git a/cc/output/direct_renderer.h b/cc/output/direct_renderer.h
index 623c7e7..8153e8ee 100644
--- a/cc/output/direct_renderer.h
+++ b/cc/output/direct_renderer.h
@@ -177,11 +177,13 @@
 
   // Whether it's valid to SwapBuffers with an empty rect. Trivially true when
   // using partial swap.
-  bool allow_empty_swap_;
+  bool allow_empty_swap_ = false;
   // Whether partial swap can be used.
-  bool use_partial_swap_;
+  bool use_partial_swap_ = false;
   // Whether overdraw feedback is enabled and can be used.
   bool overdraw_feedback_ = false;
+  // Whether the SetDrawRectangle command is in use.
+  bool use_set_draw_rectangle_ = false;
 
   // TODO(danakj): Just use a vector of pairs here? Hash map is way overkill.
   std::unordered_map<int, std::unique_ptr<ScopedResource>>
diff --git a/cc/output/gl_renderer_unittest.cc b/cc/output/gl_renderer_unittest.cc
index d7bf09e3..59d711d1 100644
--- a/cc/output/gl_renderer_unittest.cc
+++ b/cc/output/gl_renderer_unittest.cc
@@ -1532,6 +1532,7 @@
                     bool has_alpha,
                     bool use_stencil));
   MOCK_METHOD0(BindFramebuffer, void());
+  MOCK_METHOD1(SetDrawRectangle, void(const gfx::Rect&));
   MOCK_METHOD0(GetFramebufferCopyTextureFormat, GLenum());
   MOCK_METHOD1(SwapBuffers_, void(OutputSurfaceFrame& frame));  // NOLINT
   void SwapBuffers(OutputSurfaceFrame frame) override { SwapBuffers_(frame); }
@@ -1899,19 +1900,27 @@
 
 class PartialSwapMockGLES2Interface : public TestGLES2Interface {
  public:
+  explicit PartialSwapMockGLES2Interface(bool support_set_draw_rectangle)
+      : support_set_draw_rectangle_(support_set_draw_rectangle) {}
+
   void InitializeTestContext(TestWebGraphicsContext3D* context) override {
     context->set_have_post_sub_buffer(true);
+    context->set_support_set_draw_rectangle(support_set_draw_rectangle_);
   }
 
   MOCK_METHOD1(Enable, void(GLenum cap));
   MOCK_METHOD1(Disable, void(GLenum cap));
   MOCK_METHOD4(Scissor, void(GLint x, GLint y, GLsizei width, GLsizei height));
+
+ private:
+  bool support_set_draw_rectangle_;
 };
 
 class GLRendererPartialSwapTest : public GLRendererTest {
  protected:
-  void RunTest(bool partial_swap) {
-    auto gl_owned = base::MakeUnique<PartialSwapMockGLES2Interface>();
+  void RunTest(bool partial_swap, bool set_draw_rectangle) {
+    auto gl_owned =
+        base::MakeUnique<PartialSwapMockGLES2Interface>(set_draw_rectangle);
     auto* gl = gl_owned.get();
 
     auto provider = TestContextProvider::Create(std::move(gl_owned));
@@ -1955,12 +1964,19 @@
       // Partial frame, we should use a scissor to swap only that part when
       // partial swap is enabled.
       root_pass->damage_rect = gfx::Rect(2, 2, 3, 3);
+      gfx::Rect output_rectangle =
+          partial_swap ? root_pass->damage_rect : gfx::Rect(viewport_size);
 
-      if (partial_swap) {
+      if (partial_swap || set_draw_rectangle) {
         EXPECT_CALL(*gl, Enable(GL_SCISSOR_TEST)).InSequence(seq);
         // The scissor is flipped, so subtract the y coord and height from the
         // bottom of the GL viewport.
-        EXPECT_CALL(*gl, Scissor(2, viewport_size.height() - 3 - 2, 3, 3))
+        EXPECT_CALL(
+            *gl,
+            Scissor(output_rectangle.x(),
+                    viewport_size.height() - output_rectangle.y() -
+                        output_rectangle.height(),
+                    output_rectangle.width(), output_rectangle.height()))
             .InSequence(seq);
       }
 
@@ -1973,16 +1989,27 @@
       renderer.DecideRenderPassAllocationsForFrame(
           render_passes_in_draw_order_);
       DrawFrame(&renderer, viewport_size);
+      if (set_draw_rectangle) {
+        EXPECT_EQ(output_rectangle, output_surface->last_set_draw_rectangle());
+      }
     }
   }
 };
 
 TEST_F(GLRendererPartialSwapTest, PartialSwap) {
-  RunTest(true);
+  RunTest(true, false);
 }
 
 TEST_F(GLRendererPartialSwapTest, NoPartialSwap) {
-  RunTest(false);
+  RunTest(false, false);
+}
+
+TEST_F(GLRendererPartialSwapTest, SetDrawRectangle_PartialSwap) {
+  RunTest(true, true);
+}
+
+TEST_F(GLRendererPartialSwapTest, SetDrawRectangle_NoPartialSwap) {
+  RunTest(false, true);
 }
 
 class GLRendererWithMockContextTest : public ::testing::Test {
diff --git a/cc/output/output_surface.h b/cc/output/output_surface.h
index 740039c..32179f2 100644
--- a/cc/output/output_surface.h
+++ b/cc/output/output_surface.h
@@ -83,6 +83,11 @@
   // OutputSurfaces.
   virtual void BindFramebuffer() = 0;
 
+  // Marks that the given rectangle will be drawn to on the default, bound
+  // framebuffer. Only valid for surfaces with set_draw_rectangle in the
+  // context capabilities.
+  virtual void SetDrawRectangle(const gfx::Rect& rect) = 0;
+
   // Get the class capable of informing cc of hardware overlay capability.
   virtual OverlayCandidateValidator* GetOverlayCandidateValidator() const = 0;
 
diff --git a/cc/output/overlay_unittest.cc b/cc/output/overlay_unittest.cc
index d4a8e17..d36d1db 100644
--- a/cc/output/overlay_unittest.cc
+++ b/cc/output/overlay_unittest.cc
@@ -172,6 +172,7 @@
   void BindFramebuffer() override {
     bind_framebuffer_count_ += 1;
   }
+  void SetDrawRectangle(const gfx::Rect& rect) override {}
   void Reshape(const gfx::Size& size,
                float device_scale_factor,
                const gfx::ColorSpace& color_space,
diff --git a/cc/playback/display_item_list.cc b/cc/playback/display_item_list.cc
index 0febc88..dc40961f 100644
--- a/cc/playback/display_item_list.cc
+++ b/cc/playback/display_item_list.cc
@@ -118,12 +118,10 @@
       << inputs_.visual_rects.size();
   rtree_.Build(inputs_.visual_rects);
 
-  // TODO(wkorman): Restore the below, potentially with a switch to allow
-  // clearing visual rects except for Blimp engine. http://crbug.com/633750
-  // if (!retain_visual_rects_)
-  //   // This clears both the vector and the vector's capacity, since
-  //   // visual_rects won't be used anymore.
-  //   std::vector<gfx::Rect>().swap(inputs_.visual_rects);
+  if (!retain_visual_rects_)
+    // This clears both the vector and the vector's capacity, since
+    // visual_rects won't be used anymore.
+    std::vector<gfx::Rect>().swap(inputs_.visual_rects);
 }
 
 bool DisplayItemList::IsSuitableForGpuRasterization() const {
@@ -142,8 +140,6 @@
   size_t memory_usage = sizeof(*this);
 
   size_t external_memory_usage = 0;
-  // Warning: this double-counts SkPicture data if use_cached_picture is
-  // also true.
   for (const auto& item : inputs_.items) {
     size_t bytes = 0;
     switch (item.type()) {
@@ -246,7 +242,7 @@
 }
 
 void DisplayItemList::GenerateDiscardableImagesMetadata() {
-  // This should be only called once, and only after CreateAndCacheSkPicture.
+  // This should be only called once.
   DCHECK(image_map_.empty());
 
   gfx::Rect bounds = rtree_.GetBounds();
diff --git a/cc/surfaces/compositor_frame_sink_support_unittest.cc b/cc/surfaces/compositor_frame_sink_support_unittest.cc
index efa9b1b..ed7bea29 100644
--- a/cc/surfaces/compositor_frame_sink_support_unittest.cc
+++ b/cc/surfaces/compositor_frame_sink_support_unittest.cc
@@ -723,5 +723,206 @@
   EXPECT_THAT(GetChildReferences(parent_id), UnorderedElementsAre(child_id2));
 }
 
+// Checks whether the latency info are moved to the new surface from the old
+// one when LocalSurfaceId changes. No frame has unresolved dependencies.
+TEST_F(CompositorFrameSinkSupportTest,
+       LatencyInfoCarriedOverOnResize_NoUnresolvedDependencies) {
+  const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
+  const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
+  const ui::LatencyComponentType latency_type1 =
+      ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT;
+  const int64_t latency_id1 = 234;
+  const int64_t latency_sequence_number1 = 5645432;
+  const ui::LatencyComponentType latency_type2 = ui::TAB_SHOW_COMPONENT;
+  const int64_t latency_id2 = 31434351;
+  const int64_t latency_sequence_number2 = 663788;
+
+  // Submit a frame with latency info
+  ui::LatencyInfo info;
+  info.AddLatencyNumber(latency_type1, latency_id1, latency_sequence_number1);
+
+  CompositorFrame frame;
+  frame.metadata.latency_info.push_back(info);
+
+  parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
+                                         std::move(frame));
+
+  // Verify that the old surface has an active frame and no pending frame.
+  Surface* old_surface = surface_manager().GetSurfaceForId(parent_id1);
+  ASSERT_NE(nullptr, old_surface);
+  EXPECT_TRUE(old_surface->HasActiveFrame());
+  EXPECT_FALSE(old_surface->HasPendingFrame());
+
+  // Submit another frame with some other latency info and a different
+  // LocalSurfaceId.
+  ui::LatencyInfo info2;
+  info2.AddLatencyNumber(latency_type2, latency_id2, latency_sequence_number2);
+
+  CompositorFrame frame2;
+  frame2.metadata.latency_info.push_back(info2);
+
+  parent_support().SubmitCompositorFrame(parent_id2.local_surface_id(),
+                                         std::move(frame2));
+
+  // Verify that the new surface has an active frame and no pending frames.
+  Surface* surface = surface_manager().GetSurfaceForId(parent_id2);
+  ASSERT_NE(nullptr, surface);
+  EXPECT_TRUE(surface->HasActiveFrame());
+  EXPECT_FALSE(surface->HasPendingFrame());
+
+  // Verify that the new surface has both latency info elements.
+  std::vector<ui::LatencyInfo> info_list;
+  surface->TakeLatencyInfo(&info_list);
+  EXPECT_EQ(2u, info_list.size());
+
+  ui::LatencyInfo aggregated_latency_info = info_list[0];
+  aggregated_latency_info.AddNewLatencyFrom(info_list[1]);
+  EXPECT_EQ(2u, aggregated_latency_info.latency_components().size());
+
+  ui::LatencyInfo::LatencyComponent comp1;
+  EXPECT_TRUE(
+      aggregated_latency_info.FindLatency(latency_type1, latency_id1, &comp1));
+  EXPECT_EQ(latency_sequence_number1, comp1.sequence_number);
+}
+
+// Checks whether the latency info are moved to the new surface from the old
+// one when LocalSurfaceId changes. Old surface has unresolved dependencies.
+TEST_F(CompositorFrameSinkSupportTest,
+       LatencyInfoCarriedOverOnResize_OldSurfaceHasPendingAndActiveFrame) {
+  const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
+  const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
+  const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
+
+  const ui::LatencyComponentType latency_type1 =
+      ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT;
+  const int64_t latency_id1 = 234;
+  const int64_t latency_sequence_number1 = 5645432;
+  const ui::LatencyComponentType latency_type2 = ui::TAB_SHOW_COMPONENT;
+  const int64_t latency_id2 = 31434351;
+  const int64_t latency_sequence_number2 = 663788;
+
+  // Submit a frame with no unresolved dependecy.
+  ui::LatencyInfo info;
+  info.AddLatencyNumber(latency_type1, latency_id1, latency_sequence_number1);
+
+  CompositorFrame frame;
+  frame.metadata.latency_info.push_back(info);
+
+  parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
+                                         std::move(frame));
+
+  // Submit a frame with unresolved dependencies.
+  ui::LatencyInfo info2;
+  info2.AddLatencyNumber(latency_type2, latency_id2, latency_sequence_number2);
+
+  CompositorFrame frame2 = MakeCompositorFrame({child_id});
+  frame2.metadata.latency_info.push_back(info2);
+
+  parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
+                                         std::move(frame2));
+
+  // Verify that the old surface has both an active and a pending frame.
+  Surface* old_surface = surface_manager().GetSurfaceForId(parent_id1);
+  ASSERT_NE(nullptr, old_surface);
+  EXPECT_TRUE(old_surface->HasActiveFrame());
+  EXPECT_TRUE(old_surface->HasPendingFrame());
+
+  // Submit a frame with a new local surface id.
+  parent_support().SubmitCompositorFrame(parent_id2.local_surface_id(),
+                                         CompositorFrame());
+
+  // Verify that the new surface has an active frame only.
+  Surface* surface = surface_manager().GetSurfaceForId(parent_id2);
+  ASSERT_NE(nullptr, surface);
+  EXPECT_TRUE(surface->HasActiveFrame());
+  EXPECT_FALSE(surface->HasPendingFrame());
+
+  // Verify that the new surface has latency info from both active and pending
+  // frame of the old surface.
+  std::vector<ui::LatencyInfo> info_list;
+  surface->TakeLatencyInfo(&info_list);
+  EXPECT_EQ(2u, info_list.size());
+
+  ui::LatencyInfo aggregated_latency_info = info_list[0];
+  aggregated_latency_info.AddNewLatencyFrom(info_list[1]);
+  EXPECT_EQ(2u, aggregated_latency_info.latency_components().size());
+
+  ui::LatencyInfo::LatencyComponent comp1;
+  EXPECT_TRUE(
+      aggregated_latency_info.FindLatency(latency_type1, latency_id1, &comp1));
+  EXPECT_EQ(latency_sequence_number1, comp1.sequence_number);
+}
+
+// Checks whether the latency info are moved to the new surface from the old
+// one when LocalSurfaceId changes. The new surface has unresolved dependencies.
+TEST_F(CompositorFrameSinkSupportTest,
+       LatencyInfoCarriedOverOnResize_NewSurfaceHasPendingFrame) {
+  const SurfaceId parent_id1 = MakeSurfaceId(kParentFrameSink, 1);
+  const SurfaceId parent_id2 = MakeSurfaceId(kParentFrameSink, 2);
+  const SurfaceId child_id = MakeSurfaceId(kChildFrameSink1, 1);
+
+  const ui::LatencyComponentType latency_type1 =
+      ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT;
+  const int64_t latency_id1 = 234;
+  const int64_t latency_sequence_number1 = 5645432;
+  const ui::LatencyComponentType latency_type2 = ui::TAB_SHOW_COMPONENT;
+  const int64_t latency_id2 = 31434351;
+  const int64_t latency_sequence_number2 = 663788;
+
+  // Submit a frame with no unresolved dependencies.
+  ui::LatencyInfo info;
+  info.AddLatencyNumber(latency_type1, latency_id1, latency_sequence_number1);
+
+  CompositorFrame frame;
+  frame.metadata.latency_info.push_back(info);
+
+  parent_support().SubmitCompositorFrame(parent_id1.local_surface_id(),
+                                         std::move(frame));
+
+  // Verify that the old surface has an active frame only.
+  Surface* old_surface = surface_manager().GetSurfaceForId(parent_id1);
+  ASSERT_NE(nullptr, old_surface);
+  EXPECT_TRUE(old_surface->HasActiveFrame());
+  EXPECT_FALSE(old_surface->HasPendingFrame());
+
+  // Submit a frame with a new local surface id and with unresolved
+  // dependencies.
+  ui::LatencyInfo info2;
+  info2.AddLatencyNumber(latency_type2, latency_id2, latency_sequence_number2);
+
+  CompositorFrame frame2 = MakeCompositorFrame({child_id});
+  frame2.metadata.latency_info.push_back(info2);
+
+  parent_support().SubmitCompositorFrame(parent_id2.local_surface_id(),
+                                         std::move(frame2));
+
+  // Verify that the new surface has a pending frame and no active frame.
+  Surface* surface = surface_manager().GetSurfaceForId(parent_id2);
+  ASSERT_NE(nullptr, surface);
+  EXPECT_TRUE(surface->HasPendingFrame());
+  EXPECT_FALSE(surface->HasActiveFrame());
+
+  // Resolve the dependencies. The frame in parent's surface must become active.
+  child_support1().SubmitCompositorFrame(child_id.local_surface_id(),
+                                         CompositorFrame());
+  EXPECT_FALSE(surface->HasPendingFrame());
+  EXPECT_TRUE(surface->HasActiveFrame());
+
+  // Both latency info elements must exist in the now-activated frame of the
+  // new surface.
+  std::vector<ui::LatencyInfo> info_list;
+  surface->TakeLatencyInfo(&info_list);
+  EXPECT_EQ(2u, info_list.size());
+
+  ui::LatencyInfo aggregated_latency_info = info_list[0];
+  aggregated_latency_info.AddNewLatencyFrom(info_list[1]);
+  EXPECT_EQ(2u, aggregated_latency_info.latency_components().size());
+
+  ui::LatencyInfo::LatencyComponent comp1;
+  EXPECT_TRUE(
+      aggregated_latency_info.FindLatency(latency_type1, latency_id1, &comp1));
+  EXPECT_EQ(latency_sequence_number1, comp1.sequence_number);
+}
+
 }  // namespace test
 }  // namespace cc
diff --git a/cc/surfaces/surface.cc b/cc/surfaces/surface.cc
index 393b768..4aa7a436 100644
--- a/cc/surfaces/surface.cc
+++ b/cc/surfaces/surface.cc
@@ -50,9 +50,14 @@
   DCHECK(surface);
   frame_index_ = surface->frame_index() + 1;
   previous_frame_surface_id_ = surface->surface_id();
+  CompositorFrame& frame = active_frame_ ? *active_frame_ : *pending_frame_;
+  surface->TakeLatencyInfo(&frame.metadata.latency_info);
+  surface->TakeLatencyInfoFromPendingFrame(&frame.metadata.latency_info);
 }
 
 void Surface::QueueFrame(CompositorFrame frame, const DrawCallback& callback) {
+  TakeLatencyInfoFromPendingFrame(&frame.metadata.latency_info);
+
   base::Optional<CompositorFrame> previous_pending_frame =
       std::move(pending_frame_);
   pending_frame_.reset();
@@ -278,14 +283,7 @@
 void Surface::TakeLatencyInfo(std::vector<ui::LatencyInfo>* latency_info) {
   if (!active_frame_)
     return;
-  if (latency_info->empty()) {
-    active_frame_->metadata.latency_info.swap(*latency_info);
-    return;
-  }
-  std::copy(active_frame_->metadata.latency_info.begin(),
-            active_frame_->metadata.latency_info.end(),
-            std::back_inserter(*latency_info));
-  active_frame_->metadata.latency_info.clear();
+  TakeLatencyInfoFromFrame(&active_frame_.value(), latency_info);
 }
 
 void Surface::RunDrawCallbacks() {
@@ -331,4 +329,25 @@
   }
 }
 
+void Surface::TakeLatencyInfoFromPendingFrame(
+    std::vector<ui::LatencyInfo>* latency_info) {
+  if (!pending_frame_)
+    return;
+  TakeLatencyInfoFromFrame(&pending_frame_.value(), latency_info);
+}
+
+// static
+void Surface::TakeLatencyInfoFromFrame(
+    CompositorFrame* frame,
+    std::vector<ui::LatencyInfo>* latency_info) {
+  if (latency_info->empty()) {
+    frame->metadata.latency_info.swap(*latency_info);
+    return;
+  }
+  std::copy(frame->metadata.latency_info.begin(),
+            frame->metadata.latency_info.end(),
+            std::back_inserter(*latency_info));
+  frame->metadata.latency_info.clear();
+}
+
 }  // namespace cc
diff --git a/cc/surfaces/surface.h b/cc/surfaces/surface.h
index c42292e..f35740a 100644
--- a/cc/surfaces/surface.h
+++ b/cc/surfaces/surface.h
@@ -132,6 +132,12 @@
   void UnrefFrameResources(const CompositorFrame& frame_data);
   void ClearCopyRequests();
 
+  void TakeLatencyInfoFromPendingFrame(
+      std::vector<ui::LatencyInfo>* latency_info);
+  static void TakeLatencyInfoFromFrame(
+      CompositorFrame* frame,
+      std::vector<ui::LatencyInfo>* latency_info);
+
   SurfaceId surface_id_;
   SurfaceId previous_frame_surface_id_;
   base::WeakPtr<SurfaceFactory> factory_;
diff --git a/cc/test/fake_output_surface.cc b/cc/test/fake_output_surface.cc
index 07cd5b7..6c63f464 100644
--- a/cc/test/fake_output_surface.cc
+++ b/cc/test/fake_output_surface.cc
@@ -58,6 +58,10 @@
   context_provider_->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, framebuffer_);
 }
 
+void FakeOutputSurface::SetDrawRectangle(const gfx::Rect& rect) {
+  last_set_draw_rectangle_ = rect;
+}
+
 uint32_t FakeOutputSurface::GetFramebufferCopyTextureFormat() {
   if (framebuffer_)
     return framebuffer_format_;
diff --git a/cc/test/fake_output_surface.h b/cc/test/fake_output_surface.h
index bf8ef86..05c19013 100644
--- a/cc/test/fake_output_surface.h
+++ b/cc/test/fake_output_surface.h
@@ -62,6 +62,7 @@
   void EnsureBackbuffer() override {}
   void DiscardBackbuffer() override {}
   void BindFramebuffer() override;
+  void SetDrawRectangle(const gfx::Rect& rect) override;
   void Reshape(const gfx::Size& size,
                float device_scale_factor,
                const gfx::ColorSpace& color_space,
@@ -97,6 +98,10 @@
     return last_reshape_color_space_;
   }
 
+  const gfx::Rect& last_set_draw_rectangle() {
+    return last_set_draw_rectangle_;
+  }
+
  protected:
   explicit FakeOutputSurface(scoped_refptr<ContextProvider> context_provider);
   explicit FakeOutputSurface(
@@ -111,6 +116,7 @@
   GLenum framebuffer_format_ = 0;
   OverlayCandidateValidator* overlay_candidate_validator_ = nullptr;
   gfx::ColorSpace last_reshape_color_space_;
+  gfx::Rect last_set_draw_rectangle_;
 
  private:
   void SwapBuffersAck();
diff --git a/cc/test/pixel_test_output_surface.cc b/cc/test/pixel_test_output_surface.cc
index 3078fe5..926b7eb 100644
--- a/cc/test/pixel_test_output_surface.cc
+++ b/cc/test/pixel_test_output_surface.cc
@@ -44,6 +44,8 @@
   context_provider()->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0);
 }
 
+void PixelTestOutputSurface::SetDrawRectangle(const gfx::Rect& rect) {}
+
 void PixelTestOutputSurface::Reshape(const gfx::Size& size,
                                      float device_scale_factor,
                                      const gfx::ColorSpace& color_space,
diff --git a/cc/test/pixel_test_output_surface.h b/cc/test/pixel_test_output_surface.h
index 2dcdafb7..b861d203 100644
--- a/cc/test/pixel_test_output_surface.h
+++ b/cc/test/pixel_test_output_surface.h
@@ -24,6 +24,7 @@
   void EnsureBackbuffer() override;
   void DiscardBackbuffer() override;
   void BindFramebuffer() override;
+  void SetDrawRectangle(const gfx::Rect& rect) override;
   void Reshape(const gfx::Size& size,
                float device_scale_factor,
                const gfx::ColorSpace& color_space,
diff --git a/cc/test/test_web_graphics_context_3d.h b/cc/test/test_web_graphics_context_3d.h
index b2c030d..c16db55 100644
--- a/cc/test/test_web_graphics_context_3d.h
+++ b/cc/test/test_web_graphics_context_3d.h
@@ -347,6 +347,9 @@
   void set_gpu_rasterization(bool gpu_rasterization) {
     test_capabilities_.gpu_rasterization = gpu_rasterization;
   }
+  void set_support_set_draw_rectangle(bool support) {
+    test_capabilities_.set_draw_rectangle = support;
+  }
 
   // When this context is lost, all contexts in its share group are also lost.
   void add_share_group_context(TestWebGraphicsContext3D* context3d) {
diff --git a/chrome/BUILD.gn b/chrome/BUILD.gn
index 197a7f6..900ec35 100644
--- a/chrome/BUILD.gn
+++ b/chrome/BUILD.gn
@@ -1024,6 +1024,7 @@
       "//components/crash/content/app",
       "//components/policy:generated",
       "//content/public/app:both",
+      "//headless:headless_shell_lib",
       "//pdf",
       "//third_party/cld",
     ]
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
index a11081c..8ab7675 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -13,6 +13,7 @@
 import android.view.MenuItem;
 import android.webkit.MimeTypeMap;
 
+import org.chromium.base.CollectionUtil;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.UrlConstants;
@@ -24,7 +25,8 @@
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * A {@link ContextMenuPopulator} used for showing the default Chrome context menu.
@@ -49,41 +51,28 @@
     public static final int FULLSCREEN_TAB_MODE = 2;
 
     // Items that are included in all context menus.
-    private static final int[] BASE_WHITELIST = {
-            R.id.contextmenu_copy_link_address,
-            R.id.contextmenu_call,
-            R.id.contextmenu_send_message,
-            R.id.contextmenu_add_to_contacts,
-            R.id.contextmenu_copy,
-            R.id.contextmenu_copy_link_text,
-            R.id.contextmenu_load_original_image,
-            R.id.contextmenu_save_link_as,
-            R.id.contextmenu_save_image,
-            R.id.contextmenu_share_image,
-            R.id.contextmenu_save_video,
-    };
+    private static final Set<Integer> BASE_WHITELIST = CollectionUtil.newHashSet(
+            R.id.contextmenu_copy_link_address, R.id.contextmenu_call,
+            R.id.contextmenu_send_message, R.id.contextmenu_add_to_contacts, R.id.contextmenu_copy,
+            R.id.contextmenu_copy_link_text, R.id.contextmenu_load_original_image,
+            R.id.contextmenu_save_link_as, R.id.contextmenu_save_image,
+            R.id.contextmenu_share_image, R.id.contextmenu_save_video);
 
     // Items that are included for normal Chrome browser mode.
-    private static final int[] NORMAL_MODE_WHITELIST = {
-            R.id.contextmenu_open_in_new_tab,
-            R.id.contextmenu_open_in_other_window,
-            R.id.contextmenu_open_in_incognito_tab,
-            R.id.contextmenu_save_link_as,
-            R.id.contextmenu_open_image_in_new_tab,
-            R.id.contextmenu_search_by_image,
-    };
+    private static final Set<Integer> NORMAL_MODE_WHITELIST = CollectionUtil.newHashSet(
+            R.id.contextmenu_open_in_new_tab, R.id.contextmenu_open_in_other_window,
+            R.id.contextmenu_open_in_incognito_tab, R.id.contextmenu_save_link_as,
+            R.id.contextmenu_open_image_in_new_tab, R.id.contextmenu_search_by_image);
 
     // Additional items for custom tabs mode.
-    private static final int[] CUSTOM_TAB_MODE_WHITELIST = {
+    private static final Set<Integer> CUSTOM_TAB_MODE_WHITELIST = CollectionUtil.newHashSet(
             R.id.contextmenu_open_image, R.id.contextmenu_search_by_image,
             R.id.contextmenu_open_in_new_chrome_tab, R.id.contextmenu_open_in_chrome_incognito_tab,
-            R.id.contextmenu_open_in_browser_id,
-    };
+            R.id.contextmenu_open_in_browser_id);
 
     // Additional items for fullscreen tabs mode.
-    private static final int[] FULLSCREEN_TAB_MODE_WHITELIST = {
-            R.id.menu_id_open_in_chrome
-    };
+    private static final Set<Integer> FULLSCREEN_TAB_MODE_WHITELIST =
+            CollectionUtil.newHashSet(R.id.menu_id_open_in_chrome);
 
     private final ContextMenuItemDelegate mDelegate;
     private MenuInflater mMenuInflater;
@@ -205,134 +194,155 @@
         menu.setGroupVisible(R.id.contextmenu_group_anchor, params.isAnchor());
         menu.setGroupVisible(R.id.contextmenu_group_image, params.isImage());
         menu.setGroupVisible(R.id.contextmenu_group_video, params.isVideo());
+        menu.setGroupVisible(R.id.contextmenu_group_message,
+                MailTo.isMailTo(params.getLinkUrl())
+                        || UrlUtilities.isTelScheme(params.getLinkUrl()));
 
+        Set<Integer> supportedOptions = new HashSet<>();
+        supportedOptions.addAll(BASE_WHITELIST);
+        if (mMode == FULLSCREEN_TAB_MODE) {
+            supportedOptions.addAll(FULLSCREEN_TAB_MODE_WHITELIST);
+        } else if (mMode == CUSTOM_TAB_MODE) {
+            supportedOptions.addAll(CUSTOM_TAB_MODE_WHITELIST);
+            if (!ChromePreferenceManager.getInstance().getCachedChromeDefaultBrowser()) {
+                menu.findItem(R.id.contextmenu_open_in_browser_id)
+                        .setTitle(mDelegate.getTitleForOpenTabInExternalApp());
+            }
+        } else {
+            supportedOptions.addAll(NORMAL_MODE_WHITELIST);
+        }
+
+        Set<Integer> disabledOptions = getDisabledOptions(params);
+        // Iterate through the entire menu list, if if doesn't exist in the map, don't show it.
+        for (int i = 0; i < menu.size(); i++) {
+            MenuItem item = menu.getItem(i);
+            if (!item.isVisible()) continue;
+            item.setVisible(supportedOptions.contains(item.getItemId())
+                    && !disabledOptions.contains(item.getItemId()));
+        }
+
+        // Special case for searching by image element.
+        if (supportedOptions.contains(R.id.contextmenu_search_by_image)) {
+            menu.findItem(R.id.contextmenu_search_by_image)
+                    .setTitle(context.getString(R.string.contextmenu_search_web_for_image,
+                            TemplateUrlService.getInstance()
+                                    .getDefaultSearchEngineTemplateUrl()
+                                    .getShortName()));
+        }
+    }
+
+    /**
+     * Given a set of params. It creates a list of items that should not be accessible in specific
+     * instances. Since it doesn't have access to the menu groups, they need to be filtered outside
+     * of this method.
+     * @param params The parameters used to create a list of items that should not be allowed.
+     */
+    private Set<Integer> getDisabledOptions(ContextMenuParams params) {
+        Set<Integer> disabledOptions = new HashSet<>();
         if (params.isAnchor() && !mDelegate.isOpenInOtherWindowSupported()) {
-            menu.findItem(R.id.contextmenu_open_in_other_window).setVisible(false);
+            disabledOptions.add(R.id.contextmenu_open_in_other_window);
         }
 
         if (mDelegate.isIncognito() || !mDelegate.isIncognitoSupported()) {
-            menu.findItem(R.id.contextmenu_open_in_incognito_tab).setVisible(false);
+            disabledOptions.add(R.id.contextmenu_open_in_incognito_tab);
         }
 
         if (params.getLinkText().trim().isEmpty() || params.isImage()) {
-            menu.findItem(R.id.contextmenu_copy_link_text).setVisible(false);
+            disabledOptions.add(R.id.contextmenu_copy_link_text);
         }
 
         if (params.isAnchor() && !UrlUtilities.isAcceptedScheme(params.getLinkUrl())) {
-            menu.findItem(R.id.contextmenu_open_in_other_window).setVisible(false);
-            menu.findItem(R.id.contextmenu_open_in_new_tab).setVisible(false);
-            menu.findItem(R.id.contextmenu_open_in_incognito_tab).setVisible(false);
+            disabledOptions.add(R.id.contextmenu_open_in_other_window);
+            disabledOptions.add(R.id.contextmenu_open_in_new_tab);
+            disabledOptions.add(R.id.contextmenu_open_in_incognito_tab);
         }
 
         if (MailTo.isMailTo(params.getLinkUrl())) {
-            menu.findItem(R.id.contextmenu_copy_link_text).setVisible(false);
-            menu.findItem(R.id.contextmenu_copy_link_address).setVisible(false);
-            menu.setGroupVisible(R.id.contextmenu_group_message, true);
+            disabledOptions.add(R.id.contextmenu_copy_link_text);
+            disabledOptions.add(R.id.contextmenu_copy_link_address);
             if (!mDelegate.supportsSendEmailMessage()) {
-                menu.findItem(R.id.contextmenu_send_message).setVisible(false);
+                disabledOptions.add(R.id.contextmenu_send_message);
             }
             if (TextUtils.isEmpty(MailTo.parse(params.getLinkUrl()).getTo())
                     || !mDelegate.supportsAddToContacts()) {
-                menu.findItem(R.id.contextmenu_add_to_contacts).setVisible(false);
+                disabledOptions.add(R.id.contextmenu_add_to_contacts);
             }
-            menu.findItem(R.id.contextmenu_call).setVisible(false);
+            disabledOptions.add(R.id.contextmenu_call);
         } else if (UrlUtilities.isTelScheme(params.getLinkUrl())) {
-            menu.findItem(R.id.contextmenu_copy_link_text).setVisible(false);
-            menu.findItem(R.id.contextmenu_copy_link_address).setVisible(false);
-            menu.setGroupVisible(R.id.contextmenu_group_message, true);
+            disabledOptions.add(R.id.contextmenu_copy_link_text);
+            disabledOptions.add(R.id.contextmenu_copy_link_address);
             if (!mDelegate.supportsCall()) {
-                menu.findItem(R.id.contextmenu_call).setVisible(false);
+                disabledOptions.add(R.id.contextmenu_call);
             }
             if (!mDelegate.supportsSendTextMessage()) {
-                menu.findItem(R.id.contextmenu_send_message).setVisible(false);
+                disabledOptions.add(R.id.contextmenu_send_message);
             }
             if (!mDelegate.supportsAddToContacts()) {
-                menu.findItem(R.id.contextmenu_add_to_contacts).setVisible(false);
+                disabledOptions.add(R.id.contextmenu_add_to_contacts);
             }
-        } else {
-            menu.setGroupVisible(R.id.contextmenu_group_message, false);
         }
 
-        menu.findItem(R.id.contextmenu_save_link_as).setVisible(
-                UrlUtilities.isDownloadableScheme(params.getLinkUrl()));
+        if (!UrlUtilities.isDownloadableScheme(params.getLinkUrl())) {
+            disabledOptions.add(R.id.contextmenu_save_link_as);
+        }
 
+        boolean isSrcDownloadableScheme = UrlUtilities.isDownloadableScheme(params.getSrcUrl());
         if (params.isVideo()) {
-            menu.findItem(R.id.contextmenu_save_video).setVisible(
-                    params.canSaveMedia() && UrlUtilities.isDownloadableScheme(params.getSrcUrl()));
+            boolean saveableAndDownloadable = params.canSaveMedia() && isSrcDownloadableScheme;
+            if (!saveableAndDownloadable) {
+                disabledOptions.add(R.id.contextmenu_save_video);
+            }
         } else if (params.isImage() && params.imageWasFetchedLoFi()) {
             DataReductionProxyUma.previewsLoFiContextMenuAction(
                     DataReductionProxyUma.ACTION_LOFI_LOAD_IMAGE_CONTEXT_MENU_SHOWN);
             // All image context menu items other than "Load image," "Open original image in
             // new tab," and "Copy image URL" should be disabled on Lo-Fi images.
-            menu.findItem(R.id.contextmenu_save_image).setVisible(false);
-            menu.findItem(R.id.contextmenu_open_image).setVisible(false);
-            menu.findItem(R.id.contextmenu_search_by_image).setVisible(false);
-            menu.findItem(R.id.contextmenu_share_image).setVisible(false);
+            disabledOptions.add(R.id.contextmenu_save_image);
+            disabledOptions.add(R.id.contextmenu_open_image);
+            disabledOptions.add(R.id.contextmenu_search_by_image);
+            disabledOptions.add(R.id.contextmenu_share_image);
         } else if (params.isImage() && !params.imageWasFetchedLoFi()) {
-            menu.findItem(R.id.contextmenu_load_original_image).setVisible(false);
+            disabledOptions.add(R.id.contextmenu_load_original_image);
 
-            menu.findItem(R.id.contextmenu_save_image).setVisible(
-                    UrlUtilities.isDownloadableScheme(params.getSrcUrl()));
+            if (!isSrcDownloadableScheme) {
+                disabledOptions.add(R.id.contextmenu_save_image);
+            }
 
             // Avoid showing open image option for same image which is already opened.
             if (mDelegate.getPageUrl().equals(params.getSrcUrl())) {
-                menu.findItem(R.id.contextmenu_open_image).setVisible(false);
+                disabledOptions.add(R.id.contextmenu_open_image);
             }
             final TemplateUrlService templateUrlServiceInstance = TemplateUrlService.getInstance();
-            final boolean isSearchByImageAvailable =
-                    UrlUtilities.isDownloadableScheme(params.getSrcUrl())
-                            && templateUrlServiceInstance.isLoaded()
-                            && templateUrlServiceInstance.isSearchByImageAvailable()
-                            && templateUrlServiceInstance.getDefaultSearchEngineTemplateUrl()
-                                    != null;
+            final boolean isSearchByImageAvailable = isSrcDownloadableScheme
+                    && templateUrlServiceInstance.isLoaded()
+                    && templateUrlServiceInstance.isSearchByImageAvailable()
+                    && templateUrlServiceInstance.getDefaultSearchEngineTemplateUrl() != null;
 
-            menu.findItem(R.id.contextmenu_search_by_image).setVisible(isSearchByImageAvailable);
-            if (isSearchByImageAvailable) {
-                menu.findItem(R.id.contextmenu_search_by_image).setTitle(
-                        context.getString(R.string.contextmenu_search_web_for_image,
-                                TemplateUrlService.getInstance()
-                                        .getDefaultSearchEngineTemplateUrl().getShortName()));
+            if (!isSearchByImageAvailable) {
+                disabledOptions.add(R.id.contextmenu_search_by_image);
             }
         }
 
         // Hide all items that could spawn additional tabs until FRE has been completed.
         if (!FirstRunStatus.getFirstRunFlowComplete()) {
-            menu.findItem(R.id.contextmenu_open_image_in_new_tab).setVisible(false);
-            menu.findItem(R.id.contextmenu_open_in_other_window).setVisible(false);
-            menu.findItem(R.id.contextmenu_open_in_new_tab).setVisible(false);
-            menu.findItem(R.id.contextmenu_open_in_incognito_tab).setVisible(false);
-            menu.findItem(R.id.contextmenu_search_by_image).setVisible(false);
-            menu.findItem(R.id.menu_id_open_in_chrome).setVisible(false);
+            disabledOptions.add(R.id.contextmenu_open_image_in_new_tab);
+            disabledOptions.add(R.id.contextmenu_open_in_other_window);
+            disabledOptions.add(R.id.contextmenu_open_in_new_tab);
+            disabledOptions.add(R.id.contextmenu_open_in_incognito_tab);
+            disabledOptions.add(R.id.contextmenu_search_by_image);
+            disabledOptions.add(R.id.menu_id_open_in_chrome);
         }
 
-        if (mMode == FULLSCREEN_TAB_MODE) {
-            removeUnsupportedItems(menu, FULLSCREEN_TAB_MODE_WHITELIST);
-        } else if (mMode == CUSTOM_TAB_MODE) {
-            removeUnsupportedItems(menu, CUSTOM_TAB_MODE_WHITELIST);
-            MenuItem defaultOpenMenuItem = menu.findItem(R.id.contextmenu_open_in_browser_id);
+        if (mMode == CUSTOM_TAB_MODE) {
             if (ChromePreferenceManager.getInstance().getCachedChromeDefaultBrowser()) {
-                defaultOpenMenuItem.setVisible(false);
+                disabledOptions.add(R.id.contextmenu_open_in_browser_id);
             } else {
-                menu.findItem(R.id.contextmenu_open_in_new_chrome_tab).setVisible(false);
-                menu.findItem(R.id.contextmenu_open_in_chrome_incognito_tab).setVisible(false);
-                defaultOpenMenuItem.setTitle(mDelegate.getTitleForOpenTabInExternalApp());
+                disabledOptions.add(R.id.contextmenu_open_in_new_chrome_tab);
+                disabledOptions.add(R.id.contextmenu_open_in_chrome_incognito_tab);
             }
-        } else {
-            removeUnsupportedItems(menu, NORMAL_MODE_WHITELIST);
         }
-    }
 
-    private void removeUnsupportedItems(ContextMenu menu, int[] whitelist) {
-        Arrays.sort(BASE_WHITELIST);
-        Arrays.sort(whitelist);
-        for (int i = 0; i < menu.size(); i++) {
-            MenuItem item = menu.getItem(i);
-            if (Arrays.binarySearch(whitelist, item.getItemId()) < 0
-                    && Arrays.binarySearch(BASE_WHITELIST, item.getItemId()) < 0) {
-                menu.removeItem(item.getItemId());
-                i--;
-            }
-        }
+        return disabledOptions;
     }
 
     @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java
index db94bbd5..2325a81 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchFieldTrial.java
@@ -35,30 +35,14 @@
     private static final String ENABLE_BLACKLIST = "enable_blacklist";
 
     // Translation.  All these members are private, except for usage by testing.
-    // Master switch, needed to enable any translate code for Contextual Search.
+    // Master switch, needed to disable all translate code for Contextual Search in case of an
+    // emergency.
     @VisibleForTesting
-    static final String ENABLE_TRANSLATION = "enable_translation";
-    // Switch to disable translation, but not logging, used for experiment comparison.
-    @VisibleForTesting
-    static final String DISABLE_FORCE_TRANSLATION_ONEBOX = "disable_force_translation_onebox";
-    // Disables translation when we need to auto-detect the source language (when we don't resolve).
-    @VisibleForTesting
-    static final String DISABLE_AUTO_DETECT_TRANSLATION_ONEBOX =
-            "disable_auto_detect_translation_onebox";
-    // Disables using the keyboard languages to determine the target language.
-    private static final String DISABLE_KEYBOARD_LANGUAGES_FOR_TRANSLATION =
-            "disable_keyboard_languages_for_translation";
-    // Disables using the accept-languages list to determine the target language.
-    private static final String DISABLE_ACCEPT_LANGUAGES_FOR_TRANSLATION =
-            "disable_accept_languages_for_translation";
+    static final String DISABLE_TRANSLATION = "disable_translation";
     // Enables usage of English as the target language even when it's the primary UI language.
     @VisibleForTesting
     static final String ENABLE_ENGLISH_TARGET_TRANSLATION =
             "enable_english_target_translation";
-    // Enables relying on the server to control whether the onebox is actually shown, rather
-    // than checking if translation is needed client-side based on source/target languages.
-    @VisibleForTesting
-    static final String ENABLE_SERVER_CONTROLLED_ONEBOX = "enable_server_controlled_onebox";
 
     // TODO(donnd): remove all supporting code once short-lived data collection is done.
     private static final String SCREEN_TOP_SUPPRESSION_DPS = "screen_top_suppression_dps";
@@ -73,7 +57,7 @@
     private static final String DISABLE_AMP_AS_SEPARATE_TAB = "disable_amp_as_separate_tab";
 
     // Privacy-related flags
-    private static final String ENABLE_SEND_HOME_COUNTRY = "enable_send_home_country";
+    private static final String DISABLE_SEND_HOME_COUNTRY = "disable_send_home_country";
 
     // Cached values to avoid repeated and redundant JNI operations.
     private static Boolean sEnabled;
@@ -82,20 +66,15 @@
     private static Integer sMandatoryPromoLimit;
     private static Boolean sIsPeekPromoEnabled;
     private static Integer sPeekPromoMaxCount;
-    private static Boolean sIsTranslationEnabled;
-    private static Boolean sIsForceTranslationOneboxDisabled;
-    private static Boolean sIsAutoDetectTranslationOneboxDisabled;
-    private static Boolean sIsAcceptLanguagesForTranslationDisabled;
-    private static Boolean sIsKeyboardLanguagesForTranslationDisabled;
+    private static Boolean sIsTranslationDisabled;
     private static Boolean sIsEnglishTargetTranslationEnabled;
-    private static Boolean sIsServerControlledOneboxEnabled;
     private static Integer sScreenTopSuppressionDps;
     private static Boolean sIsBarOverlapCollectionEnabled;
     private static Boolean sIsBarOverlapSuppressionEnabled;
     private static Boolean sIsOnlineDetectionDisabled;
     private static Boolean sIsAmpAsSeparateTabDisabled;
     private static Boolean sContextualSearchSingleActionsEnabled;
-    private static Boolean sCanSendHomeCountry;
+    private static Boolean sIsSendHomeCountryDisabled;
     private static Boolean sContextualSearchUrlActionsEnabled;
 
     /**
@@ -212,57 +191,13 @@
     }
 
     /**
-     * @return Whether any translate code is enabled.
+     * @return Whether all translate code is disabled.
      */
-    static boolean isTranslationEnabled() {
-        if (sIsTranslationEnabled == null) {
-            sIsTranslationEnabled = getBooleanParam(ENABLE_TRANSLATION);
+    static boolean isTranslationDisabled() {
+        if (sIsTranslationDisabled == null) {
+            sIsTranslationDisabled = getBooleanParam(DISABLE_TRANSLATION);
         }
-        return sIsTranslationEnabled.booleanValue();
-    }
-
-    /**
-     * @return Whether forcing a translation Onebox is disabled.
-     */
-    static boolean isForceTranslationOneboxDisabled() {
-        if (sIsForceTranslationOneboxDisabled == null) {
-            sIsForceTranslationOneboxDisabled = getBooleanParam(DISABLE_FORCE_TRANSLATION_ONEBOX);
-        }
-        return sIsForceTranslationOneboxDisabled.booleanValue();
-    }
-
-    /**
-     * @return Whether forcing a translation Onebox based on auto-detection of the source language
-     *         is disabled.
-     */
-    static boolean isAutoDetectTranslationOneboxDisabled() {
-        if (sIsAutoDetectTranslationOneboxDisabled == null) {
-            sIsAutoDetectTranslationOneboxDisabled = getBooleanParam(
-                    DISABLE_AUTO_DETECT_TRANSLATION_ONEBOX);
-        }
-        return sIsAutoDetectTranslationOneboxDisabled.booleanValue();
-    }
-
-    /**
-     * @return Whether considering accept-languages for translation is disabled.
-     */
-    static boolean isAcceptLanguagesForTranslationDisabled() {
-        if (sIsAcceptLanguagesForTranslationDisabled == null) {
-            sIsAcceptLanguagesForTranslationDisabled = getBooleanParam(
-                    DISABLE_ACCEPT_LANGUAGES_FOR_TRANSLATION);
-        }
-        return sIsAcceptLanguagesForTranslationDisabled.booleanValue();
-    }
-
-    /**
-     * @return Whether considering keyboards for translation is disabled.
-     */
-    static boolean isKeyboardLanguagesForTranslationDisabled() {
-        if (sIsKeyboardLanguagesForTranslationDisabled == null) {
-            sIsKeyboardLanguagesForTranslationDisabled =
-                    getBooleanParam(DISABLE_KEYBOARD_LANGUAGES_FOR_TRANSLATION);
-        }
-        return sIsKeyboardLanguagesForTranslationDisabled.booleanValue();
+        return sIsTranslationDisabled.booleanValue();
     }
 
     /**
@@ -276,16 +211,6 @@
     }
 
     /**
-     * @return Whether relying on server-control of showing the translation one-box is enabled.
-     */
-    static boolean isServerControlledOneboxEnabled() {
-        if (sIsServerControlledOneboxEnabled == null) {
-            sIsServerControlledOneboxEnabled = getBooleanParam(ENABLE_SERVER_CONTROLLED_ONEBOX);
-        }
-        return sIsServerControlledOneboxEnabled.booleanValue();
-    }
-
-    /**
      * Gets a Y value limit that will suppress a Tap near the top of the screen.
      * Any Y value less than the limit will suppress the Tap trigger.
      * @return The Y value triggering limit in DPs, a value of zero will not limit.
@@ -340,13 +265,13 @@
     }
 
     /**
-     * @return Whether sending the "home country" to Google is enabled.
+     * @return Whether sending the "home country" to Google is disabled.
      */
-    static boolean isSendHomeCountryEnabled() {
-        if (sCanSendHomeCountry == null) {
-            sCanSendHomeCountry = getBooleanParam(ENABLE_SEND_HOME_COUNTRY);
+    static boolean isSendHomeCountryDisabled() {
+        if (sIsSendHomeCountryDisabled == null) {
+            sIsSendHomeCountryDisabled = getBooleanParam(DISABLE_SEND_HOME_COUNTRY);
         }
-        return sCanSendHomeCountry.booleanValue();
+        return sIsSendHomeCountryDisabled.booleanValue();
     }
 
     // ---------------
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java
index 37bc99e4..dbb6230 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchPolicy.java
@@ -479,25 +479,8 @@
     /**
      * @return Whether any translation feature for Contextual Search is enabled.
      */
-    boolean isTranslationEnabled() {
-        return ContextualSearchFieldTrial.isTranslationEnabled();
-    }
-
-    /**
-     * @return Whether forcing a translation Onebox is disabled.
-     */
-    boolean isForceTranslationOneboxDisabled() {
-        return ContextualSearchFieldTrial.isForceTranslationOneboxDisabled();
-    }
-
-    /**
-     * @return Whether forcing a translation Onebox based on auto-detection of the source language
-     *         is disabled.
-     */
-    boolean isAutoDetectTranslationOneboxDisabled() {
-        if (isForceTranslationOneboxDisabled()) return true;
-
-        return ContextualSearchFieldTrial.isAutoDetectTranslationOneboxDisabled();
+    boolean isTranslationDisabled() {
+        return ContextualSearchFieldTrial.isTranslationDisabled();
     }
 
     /**
@@ -505,7 +488,7 @@
      *         available or privacy-enabled.
      */
     String getHomeCountry(Context context) {
-        if (!ContextualSearchFieldTrial.isSendHomeCountryEnabled()) return "";
+        if (ContextualSearchFieldTrial.isSendHomeCountryDisabled()) return "";
 
         TelephonyManager telephonyManager =
                 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTranslateController.java b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTranslateController.java
index 08316494..cd8ebf3 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTranslateController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchTranslateController.java
@@ -39,20 +39,16 @@
 
     /**
      * Force translation from the given language for the current search request,
-     * unless disabled by experiment.  Also log whenever conditions are right to translate.
+     * unless disabled by a Chrome Variation.  Also log whenever conditions are right to translate.
      * @param searchRequest The search request to force translation upon.
      * @param sourceLanguage The language to translate from, or an empty string if not known.
      */
-    void forceTranslateIfNeeded(ContextualSearchRequest searchRequest,
-            String sourceLanguage) {
-        if (!mPolicy.isTranslationEnabled()) return;
+    void forceTranslateIfNeeded(ContextualSearchRequest searchRequest, String sourceLanguage) {
+        if (mPolicy.isTranslationDisabled()) return;
 
         // Force translation if not disabled and server controlled or client logic says required.
-        boolean doForceTranslate = !mPolicy.isForceTranslationOneboxDisabled()
-                && (ContextualSearchFieldTrial.isServerControlledOneboxEnabled()
-                           || !TextUtils.isEmpty(sourceLanguage)
-                                   && mPolicy.needsTranslation(
-                                              sourceLanguage, getReadableLanguages()));
+        boolean doForceTranslate = !TextUtils.isEmpty(sourceLanguage)
+                && mPolicy.needsTranslation(sourceLanguage, getReadableLanguages());
         if (doForceTranslate && searchRequest != null) {
             searchRequest.forceTranslation(
                     sourceLanguage, mPolicy.bestTargetLanguage(getProficientLanguageList()));
@@ -70,10 +66,9 @@
     void forceAutoDetectTranslateUnlessDisabled(ContextualSearchRequest searchRequest) {
         // Always trigger translation using auto-detect when we're not resolving,
         // unless disabled by policy.
-        if (!mPolicy.isTranslationEnabled()) return;
+        if (mPolicy.isTranslationDisabled()) return;
 
-        boolean shouldAutoDetectTranslate = !mPolicy.isAutoDetectTranslationOneboxDisabled();
-        if (shouldAutoDetectTranslate && searchRequest != null) {
+        if (searchRequest != null) {
             // The translation one-box won't actually show when the source text ends up being
             // the same as the target text, so we err on over-triggering.
             searchRequest.forceAutoDetectTranslation(
@@ -81,19 +76,17 @@
         }
         // Log that conditions were right for translation, even though it may be disabled
         // for an experiment so we can compare with the counter factual data.
-        ContextualSearchUma.logTranslateOnebox(shouldAutoDetectTranslate);
+        ContextualSearchUma.logTranslateOnebox(true);
     }
 
     /**
      * Caches all the native translate language info, so we can avoid repeated JNI calls.
      */
     void cacheNativeTranslateData() {
-        if (!mPolicy.isTranslationEnabled()) return;
+        if (mPolicy.isTranslationDisabled()) return;
 
-        if (!mPolicy.isForceTranslationOneboxDisabled()) {
-            getNativeTranslateServiceTargetLanguage();
-            getNativeAcceptLanguages();
-        }
+        getNativeTranslateServiceTargetLanguage();
+        getNativeAcceptLanguages();
     }
 
     /**
@@ -138,12 +131,10 @@
             uniqueLanguages.add(trimLocaleToLanguage(primaryLanguage));
         }
         // Merge in the IME locales, if possible.
-        if (!ContextualSearchFieldTrial.isKeyboardLanguagesForTranslationDisabled()) {
-            Context context = mActivity.getApplicationContext();
-            if (context != null) {
-                for (String locale : UiUtils.getIMELocales(context)) {
-                    if (isValidLocale(locale)) uniqueLanguages.add(trimLocaleToLanguage(locale));
-                }
+        Context context = mActivity.getApplicationContext();
+        if (context != null) {
+            for (String locale : UiUtils.getIMELocales(context)) {
+                if (isValidLocale(locale)) uniqueLanguages.add(trimLocaleToLanguage(locale));
             }
         }
         return uniqueLanguages;
@@ -155,12 +146,10 @@
      */
     private List<String> getAcceptLanguages() {
         List<String> result = new ArrayList<String>();
-        if (!ContextualSearchFieldTrial.isAcceptLanguagesForTranslationDisabled()) {
-            String acceptLanguages = getNativeAcceptLanguages();
-            if (!TextUtils.isEmpty(acceptLanguages)) {
-                for (String language : acceptLanguages.split(",")) {
-                    result.add(language);
-                }
+        String acceptLanguages = getNativeAcceptLanguages();
+        if (!TextUtils.isEmpty(acceptLanguages)) {
+            for (String language : acceptLanguages.split(",")) {
+                result.add(language);
             }
         }
         return result;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
index be2cf7e..bfca14b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ContextMenuTest.java
@@ -9,6 +9,8 @@
 import android.content.Context;
 import android.support.test.filters.LargeTest;
 import android.support.test.filters.MediumTest;
+import android.support.test.filters.SmallTest;
+import android.test.MoreAsserts;
 import android.view.ContextMenu;
 import android.view.KeyEvent;
 
@@ -34,6 +36,8 @@
 import org.chromium.net.test.EmbeddedTestServer;
 
 import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicReference;
@@ -348,6 +352,80 @@
         assertEquals(imageUrl, tabModel.getTabAt(indexOfLinkPage2).getUrl());
     }
 
+    @SmallTest
+    @Feature({"Browser", "ContextMenu"})
+    @RetryOnFailure
+    public void testContextMenuRetrievesLinkOptions()
+            throws TimeoutException, InterruptedException {
+        Tab tab = getActivity().getActivityTab();
+        ContextMenu menu = ContextMenuUtils.openContextMenu(tab, "testLink");
+
+        Integer[] expectedItems = {R.id.contextmenu_open_in_new_tab,
+                R.id.contextmenu_open_in_incognito_tab, R.id.contextmenu_copy_link_address,
+                R.id.contextmenu_copy_link_text, R.id.contextmenu_save_link_as};
+        assertMenuItemsAreEqual(menu, expectedItems);
+    }
+
+    @SmallTest
+    @Feature({"Browser", "ContextMenu"})
+    @RetryOnFailure
+    public void testContextMenuRetrievesImageOptions()
+            throws TimeoutException, InterruptedException {
+        Tab tab = getActivity().getActivityTab();
+        ContextMenu menu = ContextMenuUtils.openContextMenu(tab, "testImage");
+
+        Integer[] expectedItems = {R.id.contextmenu_save_image,
+                R.id.contextmenu_open_image_in_new_tab, R.id.contextmenu_search_by_image,
+                R.id.contextmenu_share_image};
+        assertMenuItemsAreEqual(menu, expectedItems);
+    }
+
+    @SmallTest
+    @Feature({"Browser", "ContextMenu"})
+    @RetryOnFailure
+    public void testContextMenuRetrievesImageLinkOptions()
+            throws TimeoutException, InterruptedException {
+        Tab tab = getActivity().getActivityTab();
+        ContextMenu menu = ContextMenuUtils.openContextMenu(tab, "testImageLink");
+
+        Integer[] expectedItems = {R.id.contextmenu_open_in_new_tab,
+                R.id.contextmenu_open_in_incognito_tab, R.id.contextmenu_copy_link_address,
+                R.id.contextmenu_save_link_as, R.id.contextmenu_save_image,
+                R.id.contextmenu_open_image_in_new_tab, R.id.contextmenu_search_by_image,
+                R.id.contextmenu_share_image};
+        assertMenuItemsAreEqual(menu, expectedItems);
+    }
+
+    @SmallTest
+    @Feature({"Browser", "ContextMenu"})
+    @RetryOnFailure
+    public void testContextMenuRetrievesVideoOptions()
+            throws TimeoutException, InterruptedException {
+        Tab tab = getActivity().getActivityTab();
+        DOMUtils.clickNode(getActivity().getCurrentContentViewCore(), "videoDOMElement");
+        ContextMenu menu = ContextMenuUtils.openContextMenu(tab, "videoDOMElement");
+
+        Integer[] expectedItems = {R.id.contextmenu_save_video};
+        assertMenuItemsAreEqual(menu, expectedItems);
+    }
+
+    /**
+     * Takes all the visible items on the menu and compares them to a the list of expected items.
+     * @param menu A context menu that is displaying visible items.
+     * @param expectedItems A list of items that is expected to appear within a context menu. The
+     *                      list does not need to be ordered.
+     */
+    private void assertMenuItemsAreEqual(ContextMenu menu, Integer... expectedItems) {
+        List<Integer> actualItems = new ArrayList<>();
+        for (int i = 0; i < menu.size(); i++) {
+            if (menu.getItem(i).isVisible()) {
+                actualItems.add(menu.getItem(i).getItemId());
+            }
+        }
+
+        MoreAsserts.assertContentsInAnyOrder(actualItems, expectedItems);
+    }
+
     private void saveMediaFromContextMenu(String mediaDOMElement, int saveMenuID,
             String expectedFilename) throws InterruptedException, TimeoutException,
             SecurityException, IOException {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
index 2568234..e4ee7fd 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextualsearch/ContextualSearchManagerTest.java
@@ -2573,7 +2573,6 @@
      */
     @SmallTest
     @Feature({"ContextualSearch"})
-    @CommandLineFlags.Add(ContextualSearchFieldTrial.ENABLE_TRANSLATION + "=true")
     public void testTapWithLanguage() throws InterruptedException, TimeoutException {
         // Tapping a German word should trigger translation.
         simulateTapSearch("german");
@@ -2585,11 +2584,24 @@
     }
 
     /**
+     * Tests translation with a simple Tap can be disabled.
+     */
+    @SmallTest
+    @Feature({"ContextualSearch"})
+    @CommandLineFlags.Add(ContextualSearchFieldTrial.DISABLE_TRANSLATION + "=true")
+    public void testTapDisabled() throws InterruptedException, TimeoutException {
+        // Tapping a German word would normally trigger translation, but not with the above flag.
+        simulateTapSearch("german");
+
+        // Make sure we did not try to trigger translate.
+        assertFalse(mManager.getRequest().isTranslationForced());
+    }
+
+    /**
      * Tests that a simple Tap without language determination does not trigger translation.
      */
     @SmallTest
     @Feature({"ContextualSearch"})
-    @CommandLineFlags.Add(ContextualSearchFieldTrial.ENABLE_TRANSLATION + "=true")
     public void testTapWithoutLanguage() throws InterruptedException, TimeoutException {
         // Tapping an English word should NOT trigger translation.
         simulateTapSearch("search");
@@ -2599,27 +2611,10 @@
     }
 
     /**
-     * Tests that the server-controlled-onebox flag can override behavior on a simple Tap
-     * without language determination.
-     */
-    @SmallTest
-    @Feature({"ContextualSearch"})
-    @CommandLineFlags.Add({ContextualSearchFieldTrial.ENABLE_TRANSLATION + "=true",
-            ContextualSearchFieldTrial.ENABLE_SERVER_CONTROLLED_ONEBOX + "=true"})
-    public void testTapWithoutLanguageCanBeForced() throws InterruptedException, TimeoutException {
-        // Tapping an English word should trigger translation.
-        simulateTapSearch("search");
-
-        // Make sure we did try to trigger translate.
-        assertTrue(mManager.getRequest().isTranslationForced());
-    }
-
-    /**
      * Tests that a long-press does trigger translation.
      */
     @SmallTest
     @Feature({"ContextualSearch"})
-    @CommandLineFlags.Add(ContextualSearchFieldTrial.ENABLE_TRANSLATION + "=true")
     public void testLongpressTranslates() throws InterruptedException, TimeoutException {
         // LongPress on any word should trigger translation.
         simulateLongPressSearch("search");
@@ -2629,31 +2624,14 @@
     }
 
     /**
-     * Tests that a long-press does NOT trigger translation when auto-detect is disabled.
+     * Tests that a long-press does NOT trigger translation when disabled.
      */
     @SmallTest
     @Feature({"ContextualSearch"})
-    @CommandLineFlags.Add({ContextualSearchFieldTrial.ENABLE_TRANSLATION + "=true",
-            ContextualSearchFieldTrial.DISABLE_AUTO_DETECT_TRANSLATION_ONEBOX + "=true"})
-    public void testLongpressAutoDetectDisabledDoesNotTranslate()
-            throws InterruptedException, TimeoutException {
-        // Unless disabled, LongPress on any word should trigger translation.
-        simulateLongPressSearch("search");
-
-        // Make sure we did not try to trigger translate.
-        assertFalse(mManager.getRequest().isTranslationForced());
-    }
-
-    /**
-     * Tests that a long-press does NOT trigger translation when general one-box is disabled.
-     */
-    @SmallTest
-    @Feature({"ContextualSearch"})
-    @CommandLineFlags.Add({ContextualSearchFieldTrial.ENABLE_TRANSLATION + "=true",
-            ContextualSearchFieldTrial.DISABLE_FORCE_TRANSLATION_ONEBOX + "=true"})
+    @CommandLineFlags.Add(ContextualSearchFieldTrial.DISABLE_TRANSLATION + "=true")
     public void testLongpressTranslateDisabledDoesNotTranslate()
             throws InterruptedException, TimeoutException {
-        // Unless disabled, LongPress on any word should trigger translation.
+        // When disabled, LongPress on any word should not trigger translation.
         simulateLongPressSearch("search");
 
         // Make sure we did not try to trigger translate.
diff --git a/chrome/app/chrome_main.cc b/chrome/app/chrome_main.cc
index 2210192..0d7a8ad 100644
--- a/chrome/app/chrome_main.cc
+++ b/chrome/app/chrome_main.cc
@@ -22,6 +22,10 @@
 #include "services/service_manager/runner/common/client_util.h"
 #endif
 
+#if defined(OS_MACOSX)
+#include "chrome/app/chrome_main_mac.h"
+#endif
+
 #if defined(OS_WIN)
 #include "base/debug/dump_without_crashing.h"
 #include "base/win/win_util.h"
@@ -93,10 +97,14 @@
   ALLOW_UNUSED_LOCAL(command_line);
 #endif
 
-#if defined(OS_LINUX)
-  if (command_line->HasSwitch(switches::kHeadless))
+#if defined(OS_LINUX) || defined(OS_MACOSX)
+  if (command_line->HasSwitch(switches::kHeadless)) {
+#if defined(OS_MACOSX)
+    SetUpBundleOverrides();
+#endif
     return headless::HeadlessShellMain(argc, argv);
-#endif  // defined(OS_LINUX)
+  }
+#endif  // defined(OS_LINUX) || defined(OS_MACOSX)
 
 #if BUILDFLAG(ENABLE_PACKAGE_MASH_SERVICES)
   version_info::Channel channel = chrome::GetChannel();
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index f665d68..46a5d906 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -1680,19 +1680,19 @@
   <message name="IDS_KEYBOARD_DROPDOWN_TITLE" desc="Title of keyboard selection dropdown menu" meaning="Small title near keyboard dropdown menu suggesting that this is a keyboard layout selector.">
     Keyboard
   </message>
-  <message name="IDS_OOBE_WELCOME_NEXT_BUTTON_TEXT" desc="Text on 'Start to use ChromeOS' button" meaning="This is the text label displayed on the 'Next' button for the first ChromeOS initial device setup screen ('Welcome screen').">
+  <message name="IDS_OOBE_WELCOME_NEXT_BUTTON_TEXT" desc="Text on 'Start to use Chrome OS' button" meaning="This is the text label displayed on the 'Next' button for the first Chrome OS initial device setup screen ('Welcome screen').">
     Let's go
   </message>
-  <message name="IDS_OOBE_OK_BUTTON_TEXT" desc="Text on 'OK' button" meaning="This is 'OK' text for all 'OK' buttons on ChromeOS initial device setup screens.">
+  <message name="IDS_OOBE_OK_BUTTON_TEXT" desc="Text on 'OK' button" meaning="This is 'OK' text for all 'OK' buttons on Chrome OS initial device setup screens.">
     OK
   </message>
-  <message name="IDS_LANGUAGE_BUTTON_LABEL" desc="Navigation label attached to the 'Select Language' button on ChromeOS initial device setup screen" meaning="The button itself displays only current language name. But for accessibility mode we need full description of this button. So this label suggests that pressing on a button will allow to change current language and input method. And it should also include the name of currently selected language.">
+  <message name="IDS_LANGUAGE_BUTTON_LABEL" desc="Navigation label attached to the 'Select Language' button on Chrome OS initial device setup screen" meaning="The button itself displays only current language name. But for accessibility mode we need full description of this button. So this label suggests that pressing on a button will allow to change current language and input method. And it should also include the name of currently selected language.">
     Select language and keyboard button. Currently selected language is <ph name="LANGUAGE">$1<ex>English (United States)</ex></ph>.
   </message>
-  <message name="IDS_LANGUAGE_SECTION_TITLE" desc="Title of language selection screen" meaning="A title of the dialog where user should select ChromeOS UI language and default keyboard layout during initial device setup.">
+  <message name="IDS_LANGUAGE_SECTION_TITLE" desc="Title of language selection screen" meaning="A title of the dialog where user should select Chrome OS UI language and default keyboard layout during initial device setup.">
     Choose your language &amp; keyboard
   </message>
-  <message name="IDS_ACCESSIBILITY_SECTION_TITLE" desc="Title of accessibility options screen" meaning="A title of the dialog where user can control ChromeOS UI accessibility (like large cursor or screen reader) options during initial device setup.">
+  <message name="IDS_ACCESSIBILITY_SECTION_TITLE" desc="Title of accessibility options screen" meaning="A title of the dialog where user can control Chrome OS UI accessibility (like large cursor or screen reader) options during initial device setup.">
     Accessibility settings
   </message>
   <message name="IDS_ACCESSIBILITY_SECTION_HINT" desc="Under-title line on the accessibility options screen" meaning="A hint to the user what these settings do and how to update them later.">
@@ -1758,11 +1758,11 @@
   <message name="IDS_OOBE_CLOSE_ACCESSIBILITY_MENU" desc="Text to be spoken when focus is set to the close button of accessibility options menu.">
     Close accessibility menu
   </message>
-  <message name="IDS_LANGUAGE_DROPDOWN_LABEL" desc="Navigation label attached to the 'List of languages' dropdown menu on ChromeOS Language and keyboard initial device setup screen" meaning="The menu itself displays only current language name. But for accessibility mode we need full description of this menu. So this label suggests that activating a menu will allow to change current language. And it should also include the name of currently selected language.">
-    Language selection menu. Currently selected language is <ph name="LANGUAGE">$1<ex>English (United States)</ex></ph>.
+  <message name="IDS_LANGUAGE_DROPDOWN_LABEL" desc="Navigation label attached to the 'List of languages' dropdown menu on Chrome OS Language and keyboard initial device setup screen" meaning="The menu itself displays only current language name. But for accessibility mode we need full description of this menu. So this label suggests that activating a menu will allow to change current language.">
+    Select language
   </message>
-  <message name="IDS_KEYBOARD_DROPDOWN_LABEL" desc="Navigation label attached to the 'List of keyboards' dropdown menu on ChromeOS Language and keyboard initial device setup screen" meaning="The menu itself displays only current keyboard layout name. But for accessibility mode we need full description of this menu. So this label suggests that activating a menu will allow to change current input method. And it should also include the name of currently selected input method.">
-    Input method selection menu. Currently selected input method is <ph name="KEYBOARD">$1<ex>English (US)</ex></ph>.
+  <message name="IDS_KEYBOARD_DROPDOWN_LABEL" desc="Navigation label attached to the 'List of keyboards' dropdown menu on Chrome OS Language and keyboard initial device setup screen" meaning="The menu itself displays only current keyboard layout name. But for accessibility mode we need full description of this menu. So this label suggests that activating a menu will allow to change current input method.">
+    Select keyboard
   </message>
   <message name="IDS_OOBE_OTHER_LANGUAGES" desc="Option group name dividing vendor-configured languages from other available languages in out-of-box 'Select language' select control.">
     Other languages
@@ -1779,6 +1779,9 @@
   <message name="IDS_TIMEZONE_DROPDOWN_TITLE" desc="Title of timezone selection dropdown menu" meaning="Small title near timezone dropdown menu suggesting that this is a timezone selector.">
     Timezone
   </message>
+  <message name="IDS_TIMEZONE_DROPDOWN_LABEL" desc="Navigation label attached to the 'List of timezones' dropdown menu on Chrome OS Timezone initial device setup screen" meaning="The menu itself displays only current timezone name. But for accessibility mode we need full description of this menu. So this label suggests that activating a menu will allow to change current timezone.">
+    Select timezone
+  </message>
   <message name="IDS_OOBE_EULA_SECTION_TITLE" desc="Title of Terms of Service screen">
     Google Chrome OS terms
   </message>
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp
index cf5ff1ed..a8d0361 100644
--- a/chrome/app/settings_strings.grdp
+++ b/chrome/app/settings_strings.grdp
@@ -1504,6 +1504,9 @@
     <message name="IDS_SETTINGS_LANGUAGES_MANAGE_INPUT_METHODS_TITLE" desc="Name of the settings sub-page which allows enabling and disabling input methods.">
       Manage input methods
     </message>
+    <message name="IDS_SETTINGS_LANGUAGES_SHOW_IME_MENU" desc="The label for he toggle button controlling showing the IME menu in the shelf.">
+      Show input options in the shelf
+    </message>
   </if>
   <message name="IDS_SETTINGS_LANGUAGES_MANAGE_LANGUAGES_TITLE" desc="Name of the settings dialog which allows enabling additional languages.">
     Add languages
diff --git a/chrome/browser/android/banners/app_banner_infobar_delegate_android.cc b/chrome/browser/android/banners/app_banner_infobar_delegate_android.cc
index a91efcc0..1e10173 100644
--- a/chrome/browser/android/banners/app_banner_infobar_delegate_android.cc
+++ b/chrome/browser/android/banners/app_banner_infobar_delegate_android.cc
@@ -6,7 +6,6 @@
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
-#include "base/guid.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
 #include "base/timer/elapsed_timer.h"
@@ -295,12 +294,8 @@
   AppBannerSettingsHelper::RecordBannerInstallEvent(
       web_contents, shortcut_info_->url.spec(), AppBannerSettingsHelper::WEB);
 
-  if (weak_manager_) {
-    const std::string& uid = base::GenerateGUID();
-    ShortcutHelper::AddToLauncherWithSkBitmap(
-        web_contents->GetBrowserContext(), *shortcut_info_, uid,
-        *icon_.get(), weak_manager_->FetchWebappSplashScreenImageCallback(uid));
-  }
+  ShortcutHelper::AddToLauncherWithSkBitmap(web_contents, *shortcut_info_,
+                                            *icon_.get());
 
   SendBannerAccepted();
   return true;
@@ -354,8 +349,7 @@
   WebApkInstaller::FinishCallback callback =
       base::Bind(&AppBannerInfoBarDelegateAndroid::OnWebApkInstallFinished,
                   weak_ptr_factory_.GetWeakPtr());
-  ShortcutHelper::InstallWebApkWithSkBitmap(web_contents->GetBrowserContext(),
-                                            *shortcut_info_,
+  ShortcutHelper::InstallWebApkWithSkBitmap(web_contents, *shortcut_info_,
                                             *icon_.get(), callback);
   SendBannerAccepted();
 
diff --git a/chrome/browser/android/banners/app_banner_manager_android.cc b/chrome/browser/android/banners/app_banner_manager_android.cc
index 866e583..a6d0f74c 100644
--- a/chrome/browser/android/banners/app_banner_manager_android.cc
+++ b/chrome/browser/android/banners/app_banner_manager_android.cc
@@ -47,6 +47,16 @@
     shortcut_info->best_primary_icon_url = icon_url;
     shortcut_info->UpdateSource(ShortcutInfo::SOURCE_APP_BANNER);
   }
+
+  shortcut_info->ideal_splash_image_size_in_px =
+      ShortcutHelper::GetIdealSplashImageSizeInPx();
+  shortcut_info->minimum_splash_image_size_in_px =
+      ShortcutHelper::GetMinimumSplashImageSizeInPx();
+  shortcut_info->splash_image_url = ManifestIconSelector::FindBestMatchingIcon(
+      manifest.icons, shortcut_info->ideal_splash_image_size_in_px,
+      shortcut_info->minimum_splash_image_size_in_px,
+      content::Manifest::Icon::IconPurpose::ANY);
+
   return shortcut_info;
 }
 
@@ -67,25 +77,6 @@
   java_banner_manager_.Reset();
 }
 
-base::Closure AppBannerManagerAndroid::FetchWebappSplashScreenImageCallback(
-    const std::string& webapp_id) {
-  content::WebContents* contents = web_contents();
-  DCHECK(contents);
-
-  int ideal_splash_image_size_in_px =
-      ShortcutHelper::GetIdealSplashImageSizeInPx();
-  int minimum_splash_image_size_in_px =
-      ShortcutHelper::GetMinimumSplashImageSizeInPx();
-  GURL image_url = ManifestIconSelector::FindBestMatchingIcon(
-      manifest_.icons, ideal_splash_image_size_in_px,
-      minimum_splash_image_size_in_px,
-      content::Manifest::Icon::IconPurpose::ANY);
-
-  return base::Bind(&ShortcutHelper::FetchSplashScreenImage, contents,
-                    image_url, ideal_splash_image_size_in_px,
-                    minimum_splash_image_size_in_px, webapp_id);
-}
-
 const base::android::ScopedJavaGlobalRef<jobject>&
 AppBannerManagerAndroid::GetJavaBannerManager() const {
   return java_banner_manager_;
diff --git a/chrome/browser/android/banners/app_banner_manager_android.h b/chrome/browser/android/banners/app_banner_manager_android.h
index 92f8ce0..4fcdeef 100644
--- a/chrome/browser/android/banners/app_banner_manager_android.h
+++ b/chrome/browser/android/banners/app_banner_manager_android.h
@@ -56,11 +56,6 @@
   // AppBannerManager overrides.
   void RequestAppBanner(const GURL& validated_url, bool is_debug_mode) override;
 
-  // Returns a callback which fetches the splash screen image and stores it in
-  // a WebappDataStorage.
-  base::Closure FetchWebappSplashScreenImageCallback(
-      const std::string& webapp_id) override;
-
   // Registers native methods.
   static bool Register(JNIEnv* env);
 
diff --git a/chrome/browser/android/compositor/tab_content_manager.cc b/chrome/browser/android/compositor/tab_content_manager.cc
index fe40101..654e721 100644
--- a/chrome/browser/android/compositor/tab_content_manager.cc
+++ b/chrome/browser/android/compositor/tab_content_manager.cc
@@ -47,23 +47,24 @@
 
 class TabContentManager::TabReadbackRequest {
  public:
-  TabReadbackRequest(content::RenderWidgetHost* rwh,
+  TabReadbackRequest(content::RenderWidgetHostView* rwhv,
                      float thumbnail_scale,
                      const TabReadbackCallback& end_callback)
       : thumbnail_scale_(thumbnail_scale),
         end_callback_(end_callback),
         drop_after_readback_(false),
         weak_factory_(this) {
-    DCHECK(rwh);
+    DCHECK(rwhv);
     content::ReadbackRequestCallback result_callback =
         base::Bind(&TabReadbackRequest::OnFinishGetTabThumbnailBitmap,
                    weak_factory_.GetWeakPtr());
 
     SkColorType color_type = kN32_SkColorType;
-    gfx::Rect src_rect = rwh->GetView()->GetViewBounds();
-    gfx::Size dst_size(
-        gfx::ScaleToCeiledSize(src_rect.size(), thumbnail_scale_));
-    rwh->CopyFromBackingStore(src_rect, dst_size, result_callback, color_type);
+    gfx::Size view_size_on_screen = rwhv->GetViewBounds().size();
+    gfx::Size thumbnail_size(
+        gfx::ScaleToCeiledSize(view_size_on_screen, thumbnail_scale_));
+    rwhv->CopyFromSurface(gfx::Rect(), thumbnail_size, result_callback,
+                          color_type);
   }
 
   virtual ~TabReadbackRequest() {}
@@ -213,8 +214,11 @@
                                  jfloat thumbnail_scale) {
   TabAndroid* tab_android = TabAndroid::GetNativeTab(env, tab);
   DCHECK(tab_android);
-  int tab_id = tab_android->GetAndroidId();
-  GURL url = tab_android->GetURL();
+  const int tab_id = tab_android->GetAndroidId();
+  if (pending_tab_readbacks_.find(tab_id) != pending_tab_readbacks_.end() ||
+      pending_tab_readbacks_.size() >= kMaxReadbacks) {
+    return;
+  }
 
   content::WebContents* web_contents = tab_android->web_contents();
   DCHECK(web_contents);
@@ -227,20 +231,21 @@
     rvh = web_contents->GetInterstitialPage()->GetMainFrame()->
         GetRenderViewHost();
   }
-
-  if (!rvh || !rvh->GetWidget() ||
-      !rvh->GetWidget()->CanCopyFromBackingStore() ||
-      pending_tab_readbacks_.find(tab_id) != pending_tab_readbacks_.end() ||
-      pending_tab_readbacks_.size() >= kMaxReadbacks) {
+  if (!rvh)
     return;
-  }
 
-  if (thumbnail_cache_->CheckAndUpdateThumbnailMetaData(tab_id, url)) {
+  content::RenderWidgetHost* rwh = rvh->GetWidget();
+  content::RenderWidgetHostView* rwhv = rwh ? rwh->GetView() : nullptr;
+  if (!rwhv || !rwhv->IsSurfaceAvailableForCopy())
+    return;
+
+  if (thumbnail_cache_->CheckAndUpdateThumbnailMetaData(
+          tab_id, tab_android->GetURL())) {
     TabReadbackCallback readback_done_callback =
         base::Bind(&TabContentManager::PutThumbnailIntoCache,
                    weak_factory_.GetWeakPtr(), tab_id);
     pending_tab_readbacks_[tab_id] = base::MakeUnique<TabReadbackRequest>(
-        rvh->GetWidget(), thumbnail_scale, readback_done_callback);
+        rwhv, thumbnail_scale, readback_done_callback);
   }
 }
 
diff --git a/chrome/browser/android/offline_pages/recent_tab_helper.cc b/chrome/browser/android/offline_pages/recent_tab_helper.cc
index 01c2011..e8c5b4d 100644
--- a/chrome/browser/android/offline_pages/recent_tab_helper.cc
+++ b/chrome/browser/android/offline_pages/recent_tab_helper.cc
@@ -44,9 +44,6 @@
     return base::MakeUnique<offline_pages::OfflinePageMHTMLArchiver>(
         web_contents);
   }
-  scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() override {
-    return base::ThreadTaskRunnerHandle::Get();
-  }
   bool GetTabId(content::WebContents* web_contents, int* tab_id) override {
     return offline_pages::OfflinePageUtils::GetTabId(web_contents, tab_id);
   }
@@ -167,7 +164,7 @@
     return snapshots_enabled_;
 
   snapshot_controller_.reset(
-      new SnapshotController(delegate_->GetTaskRunner(), this));
+      new SnapshotController(base::ThreadTaskRunnerHandle::Get(), this));
   snapshot_controller_->Stop();  // It is reset when navigation commits.
 
   int tab_id_number = 0;
diff --git a/chrome/browser/android/offline_pages/recent_tab_helper.h b/chrome/browser/android/offline_pages/recent_tab_helper.h
index 6c43a23b..3e96a7e0d 100644
--- a/chrome/browser/android/offline_pages/recent_tab_helper.h
+++ b/chrome/browser/android/offline_pages/recent_tab_helper.h
@@ -56,7 +56,6 @@
     virtual ~Delegate() {}
     virtual std::unique_ptr<OfflinePageArchiver> CreatePageArchiver(
         content::WebContents* web_contents) = 0;
-    virtual scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() = 0;
     // There is no expectations that tab_id is always present.
     virtual bool GetTabId(content::WebContents* web_contents, int* tab_id) = 0;
     virtual bool IsLowEndDevice() = 0;
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 507bd80..91f5a3a 100644
--- a/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc
+++ b/chrome/browser/android/offline_pages/recent_tab_helper_unittest.cc
@@ -4,12 +4,13 @@
 
 #include "chrome/browser/android/offline_pages/recent_tab_helper.h"
 
+#include <memory>
+
 #include "base/memory/ptr_util.h"
-#include "base/run_loop.h"
 #include "base/strings/string16.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/test/scoped_feature_list.h"
-#include "base/test/test_mock_time_task_runner.h"
+#include "base/test/scoped_mock_time_message_loop_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "chrome/browser/android/offline_pages/offline_page_model_factory.h"
 #include "chrome/browser/android/offline_pages/request_coordinator_factory.h"
@@ -43,14 +44,12 @@
 
   explicit TestDelegate(
       OfflinePageTestArchiver::Observer* observer,
-      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
       int tab_id,
       bool tab_id_result);
   ~TestDelegate() override {}
 
   std::unique_ptr<OfflinePageArchiver> CreatePageArchiver(
         content::WebContents* web_contents) override;
-  scoped_refptr<base::SingleThreadTaskRunner> GetTaskRunner() override;
     // There is no expectations that tab_id is always present.
   bool GetTabId(content::WebContents* web_contents, int* tab_id) override;
   bool IsLowEndDevice() override { return is_low_end_device_; }
@@ -66,7 +65,6 @@
 
  private:
   OfflinePageTestArchiver::Observer* observer_;  // observer owns this.
-  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
   int tab_id_;
   bool tab_id_result_;
 
@@ -87,13 +85,14 @@
   ~RecentTabHelperTest() override {}
 
   void SetUp() override;
+  void TearDown() override;
   const std::vector<OfflinePageItem>& GetAllPages();
 
   void FailLoad(const GURL& url);
 
-  // Runs default thread.
+  // Runs main thread.
   void RunUntilIdle();
-  // Moves forward the snapshot controller's task runner.
+  // Advances main thread time to trigger the snapshot controller's timeouts.
   void FastForwardSnapshotController();
 
   // Navigates to the URL and commit as if it has been typed in the address bar.
@@ -121,10 +120,6 @@
     return nullptr;
   }
 
-  scoped_refptr<base::TestMockTimeTaskRunner>& task_runner() {
-    return task_runner_;
-  }
-
   size_t page_added_count() { return page_added_count_; }
   size_t model_removed_count() { return model_removed_count_; }
 
@@ -155,9 +150,15 @@
   size_t model_removed_count_;
   std::vector<OfflinePageItem> all_pages_;
   bool all_pages_needs_updating_;
-  scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
   base::test::ScopedFeatureList scoped_feature_list_;
 
+  // Mocks the RenderViewHostTestHarness' main thread runner. Needs to be delay
+  // initialized in SetUp() -- can't be a simple member -- since
+  // RenderViewHostTestHarness only initializes its main thread environment in
+  // its SetUp() :(.
+  std::unique_ptr<base::ScopedMockTimeMessageLoopTaskRunner>
+      mocked_main_runner_;
+
   base::WeakPtrFactory<RecentTabHelperTest> weak_ptr_factory_;
 
   DISALLOW_COPY_AND_ASSIGN(RecentTabHelperTest);
@@ -165,11 +166,9 @@
 
 TestDelegate::TestDelegate(
     OfflinePageTestArchiver::Observer* observer,
-    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
     int tab_id,
     bool tab_id_result)
     : observer_(observer),
-      task_runner_(task_runner),
       tab_id_(tab_id),
       tab_id_result_(tab_id_result) {
 }
@@ -183,10 +182,7 @@
   return std::move(archiver);
 }
 
-scoped_refptr<base::SingleThreadTaskRunner> TestDelegate::GetTaskRunner() {
-  return task_runner_;
-}
-  // There is no expectations that tab_id is always present.
+// There is no expectations that tab_id is always present.
 bool TestDelegate::GetTabId(content::WebContents* web_contents, int* tab_id) {
   *tab_id = tab_id_;
   return tab_id_result_;
@@ -199,12 +195,14 @@
       page_added_count_(0),
       model_removed_count_(0),
       all_pages_needs_updating_(true),
-      task_runner_(new base::TestMockTimeTaskRunner),
       weak_ptr_factory_(this) {}
 
 void RecentTabHelperTest::SetUp() {
   ChromeRenderViewHostTestHarness::SetUp();
 
+  mocked_main_runner_ =
+      base::MakeUnique<base::ScopedMockTimeMessageLoopTaskRunner>();
+
   scoped_feature_list_.InitAndEnableFeature(kOffliningRecentPagesFeature);
   // Sets up the factories for testing.
   OfflinePageModelFactory::GetInstance()->SetTestingFactoryAndUse(
@@ -218,7 +216,7 @@
   recent_tab_helper_ = RecentTabHelper::FromWebContents(web_contents());
 
   std::unique_ptr<TestDelegate> test_delegate(
-      new TestDelegate(this, task_runner(), kTabId, true));
+      new TestDelegate(this, kTabId, true));
   default_test_delegate_ = test_delegate.get();
   recent_tab_helper_->SetDelegate(std::move(test_delegate));
 
@@ -226,6 +224,11 @@
   model_->AddObserver(this);
 }
 
+void RecentTabHelperTest::TearDown() {
+  mocked_main_runner_.reset();
+  ChromeRenderViewHostTestHarness::TearDown();
+}
+
 void RecentTabHelperTest::FailLoad(const GURL& url) {
   controller().LoadURL(url, content::Referrer(), ui::PAGE_TRANSITION_TYPED,
                        std::string());
@@ -252,12 +255,12 @@
 }
 
 void RecentTabHelperTest::RunUntilIdle() {
-  base::RunLoop().RunUntilIdle();
+  (*mocked_main_runner_)->RunUntilIdle();
 }
 
 void RecentTabHelperTest::FastForwardSnapshotController() {
-  const size_t kLongDelayMs = 100*1000;
-  task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(kLongDelayMs));
+  constexpr base::TimeDelta kLongDelay = base::TimeDelta::FromSeconds(100);
+  (*mocked_main_runner_)->FastForwardBy(kLongDelay);
 }
 
 void RecentTabHelperTest::NavigateAndCommitTyped(const GURL& url) {
@@ -289,7 +292,6 @@
   recent_tab_helper()->DocumentOnLoadCompletedInMainFrame();
   // Move the snapshot controller's time forward so it gets past timeouts.
   FastForwardSnapshotController();
-  RunUntilIdle();
   EXPECT_TRUE(model()->is_loaded());
   EXPECT_EQ(0U, page_added_count());
   ASSERT_EQ(0U, GetAllPages().size());
@@ -319,7 +321,6 @@
   recent_tab_helper()->DocumentOnLoadCompletedInMainFrame();
   // Move the snapshot controller's time forward so it gets past timeouts.
   FastForwardSnapshotController();
-  RunUntilIdle();
   EXPECT_EQ(0U, page_added_count());
   ASSERT_EQ(0U, GetAllPages().size());
 }
@@ -328,8 +329,8 @@
 // ignored from both last_n and downloads.
 TEST_F(RecentTabHelperTest, NoTabIdNoCapture) {
   // Create delegate that returns 'false' as TabId retrieval result.
-  recent_tab_helper()->SetDelegate(base::MakeUnique<TestDelegate>(
-      this, task_runner(), kTabId, false));
+  recent_tab_helper()->SetDelegate(
+      base::MakeUnique<TestDelegate>(this, kTabId, false));
 
   NavigateAndCommit(kTestPageUrl);
   recent_tab_helper()->DocumentOnLoadCompletedInMainFrame();
@@ -375,7 +376,6 @@
   // Set page loading state to the 1st snapshot-able stage. No capture so far.
   recent_tab_helper()->DocumentAvailableInMainFrame();
   FastForwardSnapshotController();
-  RunUntilIdle();
   EXPECT_TRUE(model()->is_loaded());
   EXPECT_EQ(0U, page_added_count());
 
@@ -392,7 +392,6 @@
   // capture should happen.
   recent_tab_helper()->DocumentOnLoadCompletedInMainFrame();
   FastForwardSnapshotController();
-  RunUntilIdle();
   EXPECT_EQ(1U, page_added_count());
   EXPECT_EQ(0U, model_removed_count());
   ASSERT_EQ(1U, GetAllPages().size());
@@ -465,7 +464,6 @@
   NavigateAndCommitTyped(kTestPageUrl);
   recent_tab_helper()->DocumentAvailableInMainFrame();
   FastForwardSnapshotController();
-  RunUntilIdle();
   EXPECT_EQ(1U, page_added_count());
   EXPECT_EQ(0U, model_removed_count());
   ASSERT_EQ(1U, GetAllPages().size());
@@ -531,7 +529,6 @@
   NavigateAndCommitTyped(kTestPageUrlOther);
   recent_tab_helper()->DocumentOnLoadCompletedInMainFrame();
   FastForwardSnapshotController();
-  RunUntilIdle();
   EXPECT_EQ(1U, page_added_count());
   EXPECT_EQ(0U, model_removed_count());
   ASSERT_EQ(1U, GetAllPages().size());
@@ -642,14 +639,12 @@
   const ClientId client_id = NewDownloadClientId();
   recent_tab_helper()->ObserveAndDownloadCurrentPage(client_id, 153L);
   FastForwardSnapshotController();
-  RunUntilIdle();
   EXPECT_TRUE(model()->is_loaded());
   ASSERT_EQ(0U, GetAllPages().size());
 
   // Minimally load the page. First capture should occur.
   recent_tab_helper()->DocumentAvailableInMainFrame();
   FastForwardSnapshotController();
-  RunUntilIdle();
   ASSERT_EQ(1U, GetAllPages().size());
   const OfflinePageItem& early_page = GetAllPages()[0];
   EXPECT_EQ(kTestPageUrl, early_page.url);
@@ -659,7 +654,6 @@
   // Fully load the page. A second capture should replace the first one.
   recent_tab_helper()->DocumentOnLoadCompletedInMainFrame();
   FastForwardSnapshotController();
-  RunUntilIdle();
   EXPECT_EQ(2U, page_added_count());
   EXPECT_EQ(1U, model_removed_count());
   ASSERT_EQ(1U, GetAllPages().size());
@@ -676,7 +670,6 @@
   NavigateAndCommit(kTestPageUrl);
   recent_tab_helper()->DocumentAvailableInMainFrame();
   FastForwardSnapshotController();
-  RunUntilIdle();
   EXPECT_TRUE(model()->is_loaded());
   ASSERT_EQ(0U, GetAllPages().size());
 
@@ -691,7 +684,6 @@
 
   recent_tab_helper()->DocumentOnLoadCompletedInMainFrame();
   FastForwardSnapshotController();
-  RunUntilIdle();
   EXPECT_EQ(2U, page_added_count());
   EXPECT_EQ(1U, model_removed_count());
   ASSERT_EQ(1U, GetAllPages().size());
@@ -703,7 +695,6 @@
   NavigateAndCommit(kTestPageUrl);
   recent_tab_helper()->DocumentOnLoadCompletedInMainFrame();
   FastForwardSnapshotController();
-  RunUntilIdle();
   EXPECT_TRUE(model()->is_loaded());
   ASSERT_EQ(0U, GetAllPages().size());
 
@@ -793,7 +784,6 @@
   // Finish loading the page. Only the first request should be executed.
   recent_tab_helper()->DocumentOnLoadCompletedInMainFrame();
   FastForwardSnapshotController();
-  RunUntilIdle();
   EXPECT_EQ(1U, page_added_count());
   EXPECT_EQ(0U, model_removed_count());
   ASSERT_EQ(1U, GetAllPages().size());
diff --git a/chrome/browser/android/shortcut_helper.cc b/chrome/browser/android/shortcut_helper.cc
index c3e60da4..5e28acd 100644
--- a/chrome/browser/android/shortcut_helper.cc
+++ b/chrome/browser/android/shortcut_helper.cc
@@ -12,7 +12,7 @@
 #include "base/android/jni_string.h"
 #include "base/bind.h"
 #include "base/callback.h"
-#include "base/command_line.h"
+#include "base/guid.h"
 #include "base/strings/string16.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/sequenced_worker_pool.h"
@@ -133,14 +133,17 @@
 
 // static
 void ShortcutHelper::AddToLauncherWithSkBitmap(
-    content::BrowserContext* browser_context,
+    content::WebContents* web_contents,
     const ShortcutInfo& info,
-    const std::string& webapp_id,
-    const SkBitmap& icon_bitmap,
-    const base::Closure& splash_image_callback) {
+    const SkBitmap& icon_bitmap) {
+  std::string webapp_id = base::GenerateGUID();
   if (info.display == blink::WebDisplayModeStandalone ||
       info.display == blink::WebDisplayModeFullscreen) {
-    AddWebappWithSkBitmap(info, webapp_id, icon_bitmap, splash_image_callback);
+    AddWebappWithSkBitmap(
+        info, webapp_id, icon_bitmap,
+        base::Bind(&ShortcutHelper::FetchSplashScreenImage, web_contents,
+                   info.splash_image_url, info.ideal_splash_image_size_in_px,
+                   info.minimum_splash_image_size_in_px, webapp_id));
     GooglePlayInstallState state =
         ChromeWebApkHost::GetGooglePlayInstallState();
     if (state != GooglePlayInstallState::SUPPORTED)
@@ -152,11 +155,11 @@
 
 // static
 void ShortcutHelper::InstallWebApkWithSkBitmap(
-    content::BrowserContext* browser_context,
+    content::WebContents* web_contents,
     const ShortcutInfo& info,
     const SkBitmap& icon_bitmap,
     const WebApkInstaller::FinishCallback& callback) {
-  WebApkInstallService::Get(browser_context)
+  WebApkInstallService::Get(web_contents->GetBrowserContext())
       ->InstallAsync(info, icon_bitmap, callback);
   // Don't record metric for users who install WebAPKs via "unsigned sources"
   // flow.
diff --git a/chrome/browser/android/shortcut_helper.h b/chrome/browser/android/shortcut_helper.h
index 7a30fd3..d352f97 100644
--- a/chrome/browser/android/shortcut_helper.h
+++ b/chrome/browser/android/shortcut_helper.h
@@ -18,9 +18,8 @@
 #include "third_party/skia/include/core/SkBitmap.h"
 
 namespace content {
-class BrowserContext;
 class WebContents;
-}  // namespace content
+}
 
 // ShortcutHelper is the C++ counterpart of org.chromium.chrome.browser's
 // ShortcutHelper in Java.
@@ -36,16 +35,13 @@
   // added depends on the properties in |info|. Calls one of
   // InstallWebApkInBackgroundWithSkBitmap, AddWebappInBackgroundWithSkBitmap,
   // or AddShortcutInBackgroundWithSkBitmap.
-  static void AddToLauncherWithSkBitmap(
-      content::BrowserContext* browser_context,
-      const ShortcutInfo& info,
-      const std::string& webapp_id,
-      const SkBitmap& icon_bitmap,
-      const base::Closure& splash_image_callback);
+  static void AddToLauncherWithSkBitmap(content::WebContents* web_contents,
+                                        const ShortcutInfo& info,
+                                        const SkBitmap& icon_bitmap);
 
   // Installs WebAPK and adds shortcut to the launcher.
   static void InstallWebApkWithSkBitmap(
-      content::BrowserContext* browser_context,
+      content::WebContents* web_conetnts,
       const ShortcutInfo& info,
       const SkBitmap& icon_bitmap,
       const WebApkInstaller::FinishCallback& callback);
diff --git a/chrome/browser/android/shortcut_info.cc b/chrome/browser/android/shortcut_info.cc
index 817d877..9d2d1c4 100644
--- a/chrome/browser/android/shortcut_info.cc
+++ b/chrome/browser/android/shortcut_info.cc
@@ -10,7 +10,9 @@
       orientation(blink::WebScreenOrientationLockDefault),
       source(SOURCE_ADD_TO_HOMESCREEN_SHORTCUT),
       theme_color(content::Manifest::kInvalidOrMissingColor),
-      background_color(content::Manifest::kInvalidOrMissingColor) {}
+      background_color(content::Manifest::kInvalidOrMissingColor),
+      ideal_splash_image_size_in_px(0),
+      minimum_splash_image_size_in_px(0) {}
 
 ShortcutInfo::ShortcutInfo(const ShortcutInfo& other) = default;
 
diff --git a/chrome/browser/android/shortcut_info.h b/chrome/browser/android/shortcut_info.h
index 8c6a25f3..93657b4 100644
--- a/chrome/browser/android/shortcut_info.h
+++ b/chrome/browser/android/shortcut_info.h
@@ -56,6 +56,9 @@
   Source source;
   int64_t theme_color;
   int64_t background_color;
+  int ideal_splash_image_size_in_px;
+  int minimum_splash_image_size_in_px;
+  GURL splash_image_url;
   GURL best_primary_icon_url;
   GURL best_badge_icon_url;
   std::vector<std::string> icon_urls;
diff --git a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc
index 2dea7aa..a05a2037 100644
--- a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc
+++ b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.cc
@@ -7,7 +7,6 @@
 #include <vector>
 
 #include "base/bind.h"
-#include "base/callback.h"
 #include "base/location.h"
 #include "base/strings/string16.h"
 #include "base/task_runner_util.h"
@@ -100,13 +99,6 @@
   Send(new ChromeViewMsg_GetWebApplicationInfo(routing_id()));
 }
 
-base::Closure AddToHomescreenDataFetcher::FetchSplashScreenImageCallback(
-    const std::string& webapp_id) {
-  return base::Bind(&ShortcutHelper::FetchSplashScreenImage, web_contents(),
-                    splash_screen_url_, ideal_splash_image_size_in_px_,
-                    minimum_splash_image_size_in_px_, webapp_id);
-}
-
 void AddToHomescreenDataFetcher::OnDidGetWebApplicationInfo(
     const WebApplicationInfo& received_web_app_info) {
   is_waiting_for_web_application_info_ = false;
@@ -209,7 +201,7 @@
     const InstallableData& data) {
   badge_icon_.reset();
 
-  if (!web_contents() || !weak_observer_)
+  if (!web_contents() || !weak_observer_ || is_installable_check_complete_)
     return;
 
   is_installable_check_complete_ = true;
@@ -244,10 +236,13 @@
   }
 
   // Save the splash screen URL for the later download.
-  splash_screen_url_ = ManifestIconSelector::FindBestMatchingIcon(
+  shortcut_info_.splash_image_url = ManifestIconSelector::FindBestMatchingIcon(
       data.manifest.icons, ideal_splash_image_size_in_px_,
       minimum_splash_image_size_in_px_,
       content::Manifest::Icon::IconPurpose::ANY);
+  shortcut_info_.ideal_splash_image_size_in_px = ideal_splash_image_size_in_px_;
+  shortcut_info_.minimum_splash_image_size_in_px =
+      minimum_splash_image_size_in_px_;
 
   weak_observer_->OnUserTitleAvailable(shortcut_info_.user_title);
 
diff --git a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h
index ee209ab..73baecd3 100644
--- a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h
+++ b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher.h
@@ -5,7 +5,6 @@
 #ifndef CHROME_BROWSER_ANDROID_WEBAPPS_ADD_TO_HOMESCREEN_DATA_FETCHER_H_
 #define CHROME_BROWSER_ANDROID_WEBAPPS_ADD_TO_HOMESCREEN_DATA_FETCHER_H_
 
-#include "base/callback_forward.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
 #include "base/task/cancelable_task_tracker.h"
@@ -82,10 +81,6 @@
                              bool check_webapk_compatible,
                              Observer* observer);
 
-  // Returns a callback which fetches the splash screen image to be stored for
-  // the webapp with the specified |id|.
-  base::Closure FetchSplashScreenImageCallback(const std::string& id);
-
   // IPC message received when the initialization is finished.
   void OnDidGetWebApplicationInfo(const WebApplicationInfo& web_app_info);
 
@@ -136,7 +131,6 @@
   SkBitmap badge_icon_;
   SkBitmap primary_icon_;
   ShortcutInfo shortcut_info_;
-  GURL splash_screen_url_;
 
   base::CancelableTaskTracker favicon_task_tracker_;
   base::Timer data_timeout_timer_;
diff --git a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc
index c8bfaf1b..df56a43 100644
--- a/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc
+++ b/chrome/browser/android/webapps/add_to_homescreen_data_fetcher_unittest.cc
@@ -33,6 +33,9 @@
 #include "ui/gfx/image/image_unittest_util.h"
 #include "url/gurl.h"
 
+// TODO(zpeng): Effectively test scenarios where both timeout callback and
+// success callback are invoked. See crbug.com/697228.
+
 namespace {
 
 const char* kDefaultManifestUrl = "https://www.example.com/manifest.json";
diff --git a/chrome/browser/android/webapps/add_to_homescreen_manager.cc b/chrome/browser/android/webapps/add_to_homescreen_manager.cc
index 45b0459e..d3eac8c 100644
--- a/chrome/browser/android/webapps/add_to_homescreen_manager.cc
+++ b/chrome/browser/android/webapps/add_to_homescreen_manager.cc
@@ -6,7 +6,6 @@
 
 #include "base/android/jni_android.h"
 #include "base/android/jni_string.h"
-#include "base/guid.h"
 #include "base/location.h"
 #include "base/memory/ptr_util.h"
 #include "base/strings/string16.h"
@@ -117,11 +116,7 @@
     return;
 
   RecordAddToHomescreen();
-
-  const std::string& uid = base::GenerateGUID();
-  ShortcutHelper::AddToLauncherWithSkBitmap(
-      web_contents->GetBrowserContext(), info, uid, icon,
-      data_fetcher_->FetchSplashScreenImageCallback(uid));
+  ShortcutHelper::AddToLauncherWithSkBitmap(web_contents, info, icon);
 
   // Fire the appinstalled event.
   blink::mojom::InstallationServicePtr installation_service;
diff --git a/chrome/browser/autofill/OWNERS b/chrome/browser/autofill/OWNERS
index f01ba27..4afcbe9 100644
--- a/chrome/browser/autofill/OWNERS
+++ b/chrome/browser/autofill/OWNERS
@@ -3,3 +3,5 @@
 rogerm@chromium.org
 sebsg@chromium.org
 vabr@chromium.org
+
+# COMPONENT: UI>Browser>Autofill
diff --git a/chrome/browser/banners/app_banner_manager.cc b/chrome/browser/banners/app_banner_manager.cc
index 156fa026..36463cff 100644
--- a/chrome/browser/banners/app_banner_manager.cc
+++ b/chrome/browser/banners/app_banner_manager.cc
@@ -7,7 +7,6 @@
 #include <algorithm>
 
 #include "base/bind.h"
-#include "base/callback.h"
 #include "base/command_line.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
@@ -140,11 +139,6 @@
   event_->BannerDismissed();
 }
 
-base::Closure AppBannerManager::FetchWebappSplashScreenImageCallback(
-    const std::string& webapp_id) {
-  return base::Closure();
-}
-
 AppBannerManager::AppBannerManager(content::WebContents* web_contents)
     : content::WebContentsObserver(web_contents),
       SiteEngagementObserver(nullptr),
diff --git a/chrome/browser/banners/app_banner_manager.h b/chrome/browser/banners/app_banner_manager.h
index e043913..1425605 100644
--- a/chrome/browser/banners/app_banner_manager.h
+++ b/chrome/browser/banners/app_banner_manager.h
@@ -8,7 +8,6 @@
 #include <memory>
 #include <vector>
 
-#include "base/callback_forward.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/engagement/site_engagement_observer.h"
@@ -94,12 +93,6 @@
   // desktop platforms.
   virtual void OnAppIconFetched(const SkBitmap& bitmap) {}
 
-  // Overridden and passed through base::Bind on Android. Called after a web app
-  // banner was successfully used to add a web app to homescreen to kick off an
-  // asynchronous fetch of a splash screen icon. Not used on desktop platforms.
-  virtual base::Closure FetchWebappSplashScreenImageCallback(
-      const std::string& webapp_id);
-
  protected:
   explicit AppBannerManager(content::WebContents* web_contents);
   ~AppBannerManager() override;
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index dd7aa64..d27f78d6 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -1741,16 +1741,15 @@
   // Init the RLZ library. This just binds the dll and schedules a task on the
   // file thread to be run sometime later. If this is the first run we record
   // the installation event.
-  PrefService* pref_service = profile_->GetPrefs();
-  int ping_delay = first_run::IsChromeFirstRun() ? master_prefs_->ping_delay :
-      pref_service->GetInteger(first_run::GetPingDelayPrefName().c_str());
+  int ping_delay =
+      profile_->GetPrefs()->GetInteger(prefs::kRlzPingDelaySeconds);
   // Negative ping delay means to send ping immediately after a first search is
   // recorded.
   rlz::RLZTracker::SetRlzDelegate(
       base::WrapUnique(new ChromeRLZTrackerDelegate));
   rlz::RLZTracker::InitRlzDelayed(
       first_run::IsChromeFirstRun(), ping_delay < 0,
-      base::TimeDelta::FromMilliseconds(abs(ping_delay)),
+      base::TimeDelta::FromSeconds(abs(ping_delay)),
       ChromeRLZTrackerDelegate::IsGoogleDefaultSearch(profile_),
       ChromeRLZTrackerDelegate::IsGoogleHomepage(profile_),
       ChromeRLZTrackerDelegate::IsGoogleInStartpages(profile_));
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn
index 70b6b80..e523896 100644
--- a/chrome/browser/chromeos/BUILD.gn
+++ b/chrome/browser/chromeos/BUILD.gn
@@ -40,7 +40,7 @@
     "//ash",
     "//ash:ash_with_content",
     "//ash/autoclick/mus/public/interfaces",
-    "//ash/public/interfaces",
+    "//ash/public/cpp:ash_public_cpp",
     "//build/linux:fontconfig",
     "//chrome/browser/devtools",
     "//chrome/browser/extensions",
diff --git a/chrome/browser/chromeos/login/session/user_session_manager.cc b/chrome/browser/chromeos/login/session/user_session_manager.cc
index f01f361f4..abb9800f 100644
--- a/chrome/browser/chromeos/login/session/user_session_manager.cc
+++ b/chrome/browser/chromeos/login/session/user_session_manager.cc
@@ -1434,15 +1434,14 @@
     local_state->SetBoolean(prefs::kRLZDisabled, disabled);
   }
   // Init the RLZ library.
-  int ping_delay = profile->GetPrefs()->GetInteger(
-      ::first_run::GetPingDelayPrefName().c_str());
+  int ping_delay = profile->GetPrefs()->GetInteger(prefs::kRlzPingDelaySeconds);
   // Negative ping delay means to send ping immediately after a first search is
   // recorded.
   rlz::RLZTracker::SetRlzDelegate(
       base::WrapUnique(new ChromeRLZTrackerDelegate));
   rlz::RLZTracker::InitRlzDelayed(
       user_manager::UserManager::Get()->IsCurrentUserNew(), ping_delay < 0,
-      base::TimeDelta::FromMilliseconds(abs(ping_delay)),
+      base::TimeDelta::FromSeconds(abs(ping_delay)),
       ChromeRLZTrackerDelegate::IsGoogleDefaultSearch(profile),
       ChromeRLZTrackerDelegate::IsGoogleHomepage(profile),
       ChromeRLZTrackerDelegate::IsGoogleInStartpages(profile));
diff --git a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
index 0ebd399..1fd7393 100644
--- a/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
+++ b/chrome/browser/chromeos/policy/browser_policy_connector_chromeos.cc
@@ -123,8 +123,7 @@
           device_active_directory_policy_manager_));
     } else {
       state_keys_broker_ = base::MakeUnique<ServerBackedStateKeysBroker>(
-          chromeos::DBusThreadManager::Get()->GetSessionManagerClient(),
-          base::ThreadTaskRunnerHandle::Get());
+          chromeos::DBusThreadManager::Get()->GetSessionManagerClient());
 
       device_cloud_policy_manager_ = new DeviceCloudPolicyManagerChromeOS(
           std::move(device_cloud_policy_store),
diff --git a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
index e26994bb..9e00515 100644
--- a/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
+++ b/chrome/browser/chromeos/policy/device_cloud_policy_manager_chromeos_unittest.cc
@@ -113,8 +113,7 @@
  protected:
   DeviceCloudPolicyManagerChromeOSTest()
       : fake_cryptohome_client_(new chromeos::FakeCryptohomeClient()),
-        state_keys_broker_(&fake_session_manager_client_,
-                           base::ThreadTaskRunnerHandle::Get()),
+        state_keys_broker_(&fake_session_manager_client_),
         store_(NULL) {
     fake_statistics_provider_.SetMachineStatistic(
         chromeos::system::kSerialNumberKey, "test_sn");
diff --git a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc
index df174e2..9763f2fc 100644
--- a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc
+++ b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.cc
@@ -8,7 +8,7 @@
 
 #include "base/bind.h"
 #include "base/location.h"
-#include "base/task_runner.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "chromeos/dbus/session_manager_client.h"
 
 namespace policy {
@@ -19,19 +19,16 @@
 // state key generation, so they rotate over time. The quantum size is pretty
 // coarse though (currently 2^23 seconds), so simply polling for a new state
 // keys once a day is good enough.
-const int kPollIntervalSeconds = 60 * 60 * 24;
+constexpr base::TimeDelta kPollInterval = base::TimeDelta::FromDays(1);
 
 }  // namespace
 
 ServerBackedStateKeysBroker::ServerBackedStateKeysBroker(
-    chromeos::SessionManagerClient* session_manager_client,
-    scoped_refptr<base::TaskRunner> delayed_task_runner)
+    chromeos::SessionManagerClient* session_manager_client)
     : session_manager_client_(session_manager_client),
-      delayed_task_runner_(delayed_task_runner),
       requested_(false),
       initial_retrieval_completed_(false),
-      weak_factory_(this) {
-}
+      weak_factory_(this) {}
 
 ServerBackedStateKeysBroker::~ServerBackedStateKeysBroker() {
 }
@@ -57,6 +54,11 @@
   return;
 }
 
+// static
+base::TimeDelta ServerBackedStateKeysBroker::GetPollIntervalForTesting() {
+  return kPollInterval;
+}
+
 void ServerBackedStateKeysBroker::FetchStateKeys() {
   if (!requested_) {
     requested_ = true;
@@ -95,11 +97,11 @@
       callback->Run(state_keys_);
   }
 
-  delayed_task_runner_->PostDelayedTask(
+  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
       FROM_HERE,
       base::Bind(&ServerBackedStateKeysBroker::FetchStateKeys,
                  weak_factory_.GetWeakPtr()),
-      base::TimeDelta::FromSeconds(kPollIntervalSeconds));
+      kPollInterval);
 }
 
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.h b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.h
index de4baf7..0c987cf7 100644
--- a/chrome/browser/chromeos/policy/server_backed_state_keys_broker.h
+++ b/chrome/browser/chromeos/policy/server_backed_state_keys_broker.h
@@ -12,13 +12,8 @@
 #include "base/callback.h"
 #include "base/callback_list.h"
 #include "base/macros.h"
-#include "base/memory/ref_counted.h"
 #include "base/memory/weak_ptr.h"
 
-namespace base {
-class TaskRunner;
-}
-
 namespace chromeos {
 class SessionManagerClient;
 }
@@ -36,8 +31,7 @@
       StateKeysCallback;
 
   ServerBackedStateKeysBroker(
-      chromeos::SessionManagerClient* session_manager_client,
-      scoped_refptr<base::TaskRunner> delayed_task_runner);
+      chromeos::SessionManagerClient* session_manager_client);
   ~ServerBackedStateKeysBroker();
 
   // Registers a callback to be invoked whenever the state keys get updated.
@@ -54,6 +48,8 @@
   // invoked. See http://crbug.com/649422 for more context.
   void RequestStateKeys(const StateKeysCallback& callback);
 
+  static base::TimeDelta GetPollIntervalForTesting();
+
   // Get the set of current state keys. Empty if state keys are unavailable
   // or pending retrieval.
   const std::vector<std::string>& state_keys() const { return state_keys_; }
@@ -79,8 +75,6 @@
 
   chromeos::SessionManagerClient* session_manager_client_;
 
-  scoped_refptr<base::TaskRunner> delayed_task_runner_;
-
   // The current set of state keys.
   std::vector<std::string> state_keys_;
 
diff --git a/chrome/browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc b/chrome/browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc
index 30c4c8f..12dd2cb 100644
--- a/chrome/browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc
+++ b/chrome/browser/chromeos/policy/server_backed_state_keys_broker_unittest.cc
@@ -9,7 +9,7 @@
 #include "base/macros.h"
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
-#include "base/test/test_simple_task_runner.h"
+#include "base/test/scoped_mock_time_message_loop_task_runner.h"
 #include "chromeos/dbus/fake_session_manager_client.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -18,8 +18,7 @@
 class ServerBackedStateKeysBrokerTest : public testing::Test {
  public:
   ServerBackedStateKeysBrokerTest()
-      : task_runner_(new base::TestSimpleTaskRunner()),
-        broker_(&fake_session_manager_client_, task_runner_),
+      : broker_(&fake_session_manager_client_),
         updated_(false),
         callback_invoked_(false) {
     state_keys_.push_back("1");
@@ -47,7 +46,7 @@
 
  protected:
   base::MessageLoop loop_;
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
+  base::ScopedMockTimeMessageLoopTaskRunner mocked_main_runner_;
   chromeos::FakeSessionManagerClient fake_session_manager_client_;
   ServerBackedStateKeysBroker broker_;
   std::vector<std::string> state_keys_;
@@ -69,7 +68,7 @@
       broker_.RegisterUpdateCallback(
           base::Bind(&ServerBackedStateKeysBrokerTest::StateKeysUpdated,
                      base::Unretained(this)));
-  base::RunLoop().RunUntilIdle();
+  mocked_main_runner_->RunUntilIdle();
   EXPECT_TRUE(updated_);
   ExpectGood();
 }
@@ -82,7 +81,7 @@
       broker_.RegisterUpdateCallback(
           base::Bind(&ServerBackedStateKeysBrokerTest::StateKeysUpdated,
                      base::Unretained(this)));
-  base::RunLoop().RunUntilIdle();
+  mocked_main_runner_->RunUntilIdle();
   EXPECT_TRUE(updated_);
 
   EXPECT_FALSE(broker_.pending());
@@ -94,7 +93,7 @@
   updated_ = false;
   ServerBackedStateKeysBroker::Subscription subscription2 =
       broker_.RegisterUpdateCallback(base::Bind(&base::DoNothing));
-  base::RunLoop().RunUntilIdle();
+  mocked_main_runner_->RunUntilIdle();
   EXPECT_TRUE(updated_);
   ExpectGood();
 }
@@ -104,7 +103,7 @@
       broker_.RegisterUpdateCallback(
           base::Bind(&ServerBackedStateKeysBrokerTest::StateKeysUpdated,
                      base::Unretained(this)));
-  base::RunLoop().RunUntilIdle();
+  mocked_main_runner_->RunUntilIdle();
   EXPECT_TRUE(updated_);
   ExpectGood();
 
@@ -113,15 +112,15 @@
   state_keys_.push_back("4");
   fake_session_manager_client_.set_server_backed_state_keys(state_keys_);
   updated_ = false;
-  task_runner_->RunPendingTasks();
-  base::RunLoop().RunUntilIdle();
+  mocked_main_runner_->FastForwardBy(
+      ServerBackedStateKeysBroker::GetPollIntervalForTesting());
   EXPECT_TRUE(updated_);
   ExpectGood();
 
   // No update callback if the keys are unchanged.
   updated_ = false;
-  task_runner_->RunPendingTasks();
-  base::RunLoop().RunUntilIdle();
+  mocked_main_runner_->FastForwardBy(
+      ServerBackedStateKeysBroker::GetPollIntervalForTesting());
   EXPECT_FALSE(updated_);
   ExpectGood();
 }
@@ -130,7 +129,7 @@
   broker_.RequestStateKeys(
       base::Bind(&ServerBackedStateKeysBrokerTest::HandleStateKeysCallback,
                  base::Unretained(this)));
-  base::RunLoop().RunUntilIdle();
+  mocked_main_runner_->RunUntilIdle();
   ExpectGood();
   EXPECT_TRUE(callback_invoked_);
   EXPECT_EQ(state_keys_, callback_state_keys_);
@@ -143,7 +142,7 @@
   broker_.RequestStateKeys(
       base::Bind(&ServerBackedStateKeysBrokerTest::HandleStateKeysCallback,
                  base::Unretained(this)));
-  base::RunLoop().RunUntilIdle();
+  mocked_main_runner_->RunUntilIdle();
   EXPECT_TRUE(callback_invoked_);
   EXPECT_TRUE(callback_state_keys_.empty());
 }
diff --git a/chrome/browser/extensions/api/messaging/OWNERS b/chrome/browser/extensions/api/messaging/OWNERS
index acce01b..e156a4cb 100644
--- a/chrome/browser/extensions/api/messaging/OWNERS
+++ b/chrome/browser/extensions/api/messaging/OWNERS
@@ -4,3 +4,5 @@
 
 # For native messaging.
 sergeyu@chromium.org
+
+# COMPONENT: Platform>Extensions>API
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc
index a0054d09..60039bd 100644
--- a/chrome/browser/extensions/api/settings_private/prefs_util.cc
+++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -155,6 +155,8 @@
       settings_private::PrefType::PREF_TYPE_BOOLEAN;
   (*s_whitelist)[::prefs::kSearchSuggestEnabled] =
       settings_private::PrefType::PREF_TYPE_BOOLEAN;
+
+  // Languages page
   (*s_whitelist)[spellcheck::prefs::kSpellCheckDictionaries] =
       settings_private::PrefType::PREF_TYPE_LIST;
   (*s_whitelist)[spellcheck::prefs::kSpellCheckUseSpellingService] =
@@ -163,6 +165,10 @@
       settings_private::PrefType::PREF_TYPE_BOOLEAN;
   (*s_whitelist)[translate::TranslatePrefs::kPrefTranslateBlockedLanguages] =
       settings_private::PrefType::PREF_TYPE_LIST;
+#if defined(OS_CHROMEOS)
+  (*s_whitelist)[::prefs::kLanguageImeMenuActivated] =
+      settings_private::PrefType::PREF_TYPE_BOOLEAN;
+#endif
 
   // Search page.
   (*s_whitelist)[::prefs::kDefaultSearchProviderEnabled] =
diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc
index 0f50871..9fb95b9c 100644
--- a/chrome/browser/extensions/api/tabs/tabs_api.cc
+++ b/chrome/browser/extensions/api/tabs/tabs_api.cc
@@ -1663,7 +1663,7 @@
 
   return CaptureAsync(
       contents, image_details.get(),
-      base::Bind(&TabsCaptureVisibleTabFunction::CopyFromBackingStoreComplete,
+      base::Bind(&TabsCaptureVisibleTabFunction::CopyFromSurfaceComplete,
                  this));
 }
 
diff --git a/chrome/browser/first_run/first_run.cc b/chrome/browser/first_run/first_run.cc
index a13c299c..522b4d7 100644
--- a/chrome/browser/first_run/first_run.cc
+++ b/chrome/browser/first_run/first_run.cc
@@ -5,6 +5,7 @@
 #include "chrome/browser/first_run/first_run.h"
 
 #include <algorithm>
+#include <memory>
 #include <utility>
 
 #include "base/command_line.h"
@@ -54,7 +55,6 @@
 #include "chrome/installer/util/master_preferences.h"
 #include "chrome/installer/util/master_preferences_constants.h"
 #include "chrome/installer/util/util_constants.h"
-#include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
 #include "components/search_engines/template_url_service.h"
 #include "components/signin/core/browser/signin_manager.h"
@@ -447,10 +447,11 @@
 // object if successful; otherwise, returns NULL.
 installer::MasterPreferences* LoadMasterPrefs() {
   base::FilePath master_prefs_path;
-  if (!master_prefs_path_for_testing.Get().empty())
+  if (!master_prefs_path_for_testing.Get().empty()) {
     master_prefs_path = master_prefs_path_for_testing.Get();
-  else
+  } else {
     master_prefs_path = base::FilePath(first_run::internal::MasterPrefsPath());
+  }
   if (master_prefs_path.empty())
     return NULL;
   installer::MasterPreferences* install_prefs =
@@ -494,9 +495,6 @@
   ConvertStringVectorToGURLVector(
       install_prefs.GetFirstRunTabs(), &out_prefs->new_tabs);
 
-  install_prefs.GetInt(installer::master_preferences::kDistroPingDelay,
-                       &out_prefs->ping_delay);
-
   bool value = false;
   if (install_prefs.GetBool(
           installer::master_preferences::kDistroImportSearchPref, &value)) {
@@ -619,14 +617,12 @@
 }  // namespace internal
 
 MasterPrefs::MasterPrefs()
-    : ping_delay(0),
-      homepage_defined(false),
+    : homepage_defined(false),
       do_import_items(0),
       dont_import_items(0),
       make_chrome_default_for_user(false),
       suppress_first_run_default_browser_prompt(false),
-      welcome_page_on_os_upgrade_enabled(true) {
-}
+      welcome_page_on_os_upgrade_enabled(true) {}
 
 MasterPrefs::~MasterPrefs() {}
 
@@ -660,16 +656,6 @@
     internal::CreateSentinel();
 }
 
-std::string GetPingDelayPrefName() {
-  return base::StringPrintf("%s.%s",
-                            installer::master_preferences::kDistroDict,
-                            installer::master_preferences::kDistroPingDelay);
-}
-
-void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
-  registry->RegisterIntegerPref(GetPingDelayPrefName().c_str(), 0);
-}
-
 bool SetShowFirstRunBubblePref(FirstRunBubbleOptions show_bubble_option) {
   PrefService* local_state = g_browser_process->local_state();
   if (!local_state)
@@ -742,16 +728,21 @@
   std::unique_ptr<installer::MasterPreferences> install_prefs(
       LoadMasterPrefs());
 
-  // Default value in case master preferences is missing or corrupt, or
-  // ping_delay is missing.
-  out_prefs->ping_delay = 90;
   if (install_prefs.get()) {
     if (!internal::ShowPostInstallEULAIfNeeded(install_prefs.get()))
       return EULA_EXIT_NOW;
 
+    std::unique_ptr<base::DictionaryValue> master_dictionary =
+        install_prefs->master_dictionary().CreateDeepCopy();
+    // The distribution dictionary (and any prefs below it) are never registered
+    // for use in Chrome's PrefService. Strip them from the master dictionary
+    // before mapping it to prefs.
+    master_dictionary->RemoveWithoutPathExpansion(
+        installer::master_preferences::kDistroDict, nullptr);
+
     if (!chrome_prefs::InitializePrefsFromMasterPrefs(
             profiles::GetDefaultProfileDir(user_data_dir),
-            install_prefs->master_dictionary())) {
+            std::move(master_dictionary))) {
       DLOG(ERROR) << "Failed to initialize from master_preferences.";
     }
 
diff --git a/chrome/browser/first_run/first_run.h b/chrome/browser/first_run/first_run.h
index 001b339..725dade 100644
--- a/chrome/browser/first_run/first_run.h
+++ b/chrome/browser/first_run/first_run.h
@@ -24,10 +24,6 @@
 class WebContents;
 }
 
-namespace user_prefs {
-class PrefRegistrySyncable;
-}
-
 // This namespace contains the chrome first-run installation actions needed to
 // fully test the custom installer. It also contains the opposite actions to
 // execute during uninstall. When the first run UI is ready we won't
@@ -75,7 +71,6 @@
   // remove items from here which are being stored temporarily only to be later
   // dumped into local_state. Also see related TODO in chrome_browser_main.cc.
 
-  int ping_delay;
   bool homepage_defined;
   int do_import_items;
   int dont_import_items;
@@ -116,12 +111,6 @@
 // (http://crbug.com/264694).
 void CreateSentinelIfNeeded();
 
-// Get RLZ ping delay pref name.
-std::string GetPingDelayPrefName();
-
-// Register user preferences used by the MasterPrefs structure.
-void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
-
 // Sets the kShowFirstRunBubbleOption local state pref so that the browser
 // shows the bubble once the main message loop gets going (or refrains from
 // showing the bubble, if |show_bubble| is not FIRST_RUN_BUBBLE_SHOW).
diff --git a/chrome/browser/media/OWNERS b/chrome/browser/media/OWNERS
index 60c23922..4258926 100644
--- a/chrome/browser/media/OWNERS
+++ b/chrome/browser/media/OWNERS
@@ -5,3 +5,5 @@
 # For Cast streaming changes.
 per-file cast_*=hubbe@chromium.org
 per-file cast_*=miu@chromium.org
+
+# COMPONENT: Blink>Media
diff --git a/chrome/browser/media/webrtc/OWNERS b/chrome/browser/media/webrtc/OWNERS
index 9f599413..2de8100 100644
--- a/chrome/browser/media/webrtc/OWNERS
+++ b/chrome/browser/media/webrtc/OWNERS
@@ -7,3 +7,5 @@
 
 # For changes related to the tab media indicators.
 per-file media_stream_capture_indicator*=miu@chromium.org
+
+# COMPONENT: Blink>WebRTC
diff --git a/chrome/browser/plugins/plugin_power_saver_browsertest.cc b/chrome/browser/plugins/plugin_power_saver_browsertest.cc
index c60a6ee..e688838 100644
--- a/chrome/browser/plugins/plugin_power_saver_browsertest.cc
+++ b/chrome/browser/plugins/plugin_power_saver_browsertest.cc
@@ -28,6 +28,7 @@
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/render_widget_host.h"
+#include "content/public/browser/render_widget_host_view.h"
 #include "content/public/common/content_features.h"
 #include "content/public/common/content_switches.h"
 #include "content/public/test/browser_test_utils.h"
@@ -366,13 +367,13 @@
     content::RenderWidgetHost* rwh =
         GetActiveWebContents()->GetRenderViewHost()->GetWidget();
 
-    if (!rwh->CanCopyFromBackingStore()) {
-      ADD_FAILURE() << "Could not copy from backing store.";
+    if (!rwh->GetView() || !rwh->GetView()->IsSurfaceAvailableForCopy()) {
+      ADD_FAILURE() << "RWHV surface not available for copy.";
       return false;
     }
 
     bool snapshot_matches = false;
-    rwh->CopyFromBackingStore(
+    rwh->GetView()->CopyFromSurface(
         gfx::Rect(), gfx::Size(),
         base::Bind(&CompareSnapshotToReference, reference, &snapshot_matches,
                    base::MessageLoop::QuitWhenIdleClosure()),
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index 75ca0ce..c71e894 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -51,6 +51,7 @@
 #include "chrome/browser/profiles/profiles_state.h"
 #include "chrome/browser/push_messaging/push_messaging_app_identifier.h"
 #include "chrome/browser/renderer_host/pepper/device_id_fetcher.h"
+#include "chrome/browser/rlz/chrome_rlz_tracker_delegate.h"
 #include "chrome/browser/search/search.h"
 #include "chrome/browser/signin/signin_manager_factory.h"
 #include "chrome/browser/task_manager/task_manager_interface.h"
@@ -112,6 +113,7 @@
 #include "net/http/http_server_properties_manager.h"
 #include "ppapi/features/features.h"
 #include "printing/features/features.h"
+#include "rlz/features/features.h"
 
 #if BUILDFLAG(ENABLE_APP_LIST)
 #include "chrome/browser/apps/drive/drive_app_mapping.h"
@@ -262,37 +264,49 @@
 
 #if BUILDFLAG(ENABLE_GOOGLE_NOW)
 // Deprecated 3/2016
-const char kGoogleGeolocationAccessEnabled[] =
+constexpr char kGoogleGeolocationAccessEnabled[] =
     "googlegeolocationaccess.enabled";
 #endif
 
 // Deprecated 4/2016.
-const char kCheckDefaultBrowser[] = "browser.check_default_browser";
+constexpr char kCheckDefaultBrowser[] = "browser.check_default_browser";
 
 // Deprecated 5/2016.
-const char kDesktopSearchRedirectionInfobarShownPref[] =
+constexpr char kDesktopSearchRedirectionInfobarShownPref[] =
     "desktop_search_redirection_infobar_shown";
 
 // Deprecated 7/2016.
-const char kNetworkPredictionEnabled[] = "dns_prefetching.enabled";
-const char kDisableSpdy[] = "spdy.disabled";
+constexpr char kNetworkPredictionEnabled[] = "dns_prefetching.enabled";
+constexpr char kDisableSpdy[] = "spdy.disabled";
 
 // Deprecated 8/2016.
-const char kRecentlySelectedEncoding[] = "profile.recently_selected_encodings";
-const char kStaticEncodings[] = "intl.static_encodings";
+constexpr char kRecentlySelectedEncoding[] =
+    "profile.recently_selected_encodings";
+constexpr char kStaticEncodings[] = "intl.static_encodings";
 
 // Deprecated 9/2016.
-const char kWebKitUsesUniversalDetector[] =
+constexpr char kWebKitUsesUniversalDetector[] =
     "webkit.webprefs.uses_universal_detector";
-const char kWebKitAllowDisplayingInsecureContent[] =
+constexpr char kWebKitAllowDisplayingInsecureContent[] =
     "webkit.webprefs.allow_displaying_insecure_content";
 
 #if BUILDFLAG(ENABLE_EXTENSIONS)
 // Deprecated 2/2017.
-const char kToolbarMigratedComponentActionStatus[] =
+constexpr char kToolbarMigratedComponentActionStatus[] =
     "toolbar_migrated_component_action_status";
 #endif
 
+#if BUILDFLAG(ENABLE_RLZ)
+// Migrated out of kDistroDict as of 2/2017.
+constexpr char kDistroRlzPingDelay[] = "ping_delay";
+#endif  // BUILDFLAG(ENABLE_RLZ)
+
+// master_preferences used to be mapped as-is to Preferences on first run but
+// the "distribution" dictionary was never used beyond first run. It is now
+// stripped in first_run.cc prior to applying this mapping. Cleanup for existing
+// Preferences files added here 2/2017.
+constexpr char kDistroDict[] = "distribution";
+
 void DeleteWebRTCIdentityStoreDBOnFileThread(
     const base::FilePath& profile_path) {
   base::DeleteFile(profile_path.Append(
@@ -546,7 +560,6 @@
   extensions::CommandService::RegisterProfilePrefs(registry);
   extensions::ExtensionSettingsHandler::RegisterProfilePrefs(registry);
   extensions::TabsCaptureVisibleTabFunction::RegisterProfilePrefs(registry);
-  first_run::RegisterProfilePrefs(registry);
   NewTabUI::RegisterProfilePrefs(registry);
   PepperFlashSettingsManager::RegisterProfilePrefs(registry);
   PinnedTabCodec::RegisterProfilePrefs(registry);
@@ -597,6 +610,10 @@
   ArcAppListPrefs::RegisterProfilePrefs(registry);
 #endif
 
+#if BUILDFLAG(ENABLE_RLZ)
+  ChromeRLZTrackerDelegate::RegisterProfilePrefs(registry);
+#endif
+
 #if defined(OS_WIN)
   component_updater::RegisterProfilePrefsForSwReporter(registry);
   desktop_ios_promotion::RegisterProfilePrefs(registry);
@@ -639,6 +656,8 @@
 #if BUILDFLAG(ENABLE_EXTENSIONS)
   registry->RegisterDictionaryPref(kToolbarMigratedComponentActionStatus);
 #endif
+
+  registry->RegisterDictionaryPref(kDistroDict);
 }
 
 void RegisterUserProfilePrefs(user_prefs::PrefRegistrySyncable* registry) {
@@ -731,6 +750,20 @@
   // Added 2/2017.
   profile_prefs->ClearPref(kToolbarMigratedComponentActionStatus);
 #endif
+
+  // Added 2/2017.
+  {
+#if BUILDFLAG(ENABLE_RLZ)
+    const base::DictionaryValue* distro_dict =
+        profile_prefs->GetDictionary(kDistroDict);
+    int rlz_ping_delay = 0;
+    if (distro_dict &&
+        distro_dict->GetInteger(kDistroRlzPingDelay, &rlz_ping_delay)) {
+      profile_prefs->SetInteger(prefs::kRlzPingDelaySeconds, rlz_ping_delay);
+    }
+#endif  // BUILDFLAG(ENABLE_RLZ)
+    profile_prefs->ClearPref(kDistroDict);
+  }
 }
 
 }  // namespace chrome
diff --git a/chrome/browser/prefs/chrome_pref_service_factory.cc b/chrome/browser/prefs/chrome_pref_service_factory.cc
index 48ceeea7..4e7a23e 100644
--- a/chrome/browser/prefs/chrome_pref_service_factory.cc
+++ b/chrome/browser/prefs/chrome_pref_service_factory.cc
@@ -8,6 +8,7 @@
 #include <stddef.h>
 
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "base/bind.h"
@@ -513,9 +514,9 @@
 
 bool InitializePrefsFromMasterPrefs(
     const base::FilePath& profile_path,
-    const base::DictionaryValue& master_prefs) {
+    std::unique_ptr<base::DictionaryValue> master_prefs) {
   return CreateProfilePrefStoreManager(profile_path)
-      ->InitializePrefsFromMasterPrefs(master_prefs);
+      ->InitializePrefsFromMasterPrefs(std::move(master_prefs));
 }
 
 base::Time GetResetTime(Profile* profile) {
diff --git a/chrome/browser/prefs/chrome_pref_service_factory.h b/chrome/browser/prefs/chrome_pref_service_factory.h
index 6d3147f..679be63d 100644
--- a/chrome/browser/prefs/chrome_pref_service_factory.h
+++ b/chrome/browser/prefs/chrome_pref_service_factory.h
@@ -88,7 +88,7 @@
 // preference values in |master_prefs|. Returns true on success.
 bool InitializePrefsFromMasterPrefs(
     const base::FilePath& profile_path,
-    const base::DictionaryValue& master_prefs);
+    std::unique_ptr<base::DictionaryValue> master_prefs);
 
 // Retrieves the time of the last preference reset event, if any, for the
 // provided profile. If no reset has occurred, returns a null |Time|.
diff --git a/chrome/browser/prefs/profile_pref_store_manager.cc b/chrome/browser/prefs/profile_pref_store_manager.cc
index 98f85db..c62708d8 100644
--- a/chrome/browser/prefs/profile_pref_store_manager.cc
+++ b/chrome/browser/prefs/profile_pref_store_manager.cc
@@ -170,23 +170,18 @@
 }
 
 bool ProfilePrefStoreManager::InitializePrefsFromMasterPrefs(
-    const base::DictionaryValue& master_prefs) {
+    std::unique_ptr<base::DictionaryValue> master_prefs) {
   // Create the profile directory if it doesn't exist yet (very possible on
   // first run).
   if (!base::CreateDirectory(profile_path_))
     return false;
 
-  const base::DictionaryValue* to_serialize = &master_prefs;
-  std::unique_ptr<base::DictionaryValue> copy;
-
   if (kPlatformSupportsPreferenceTracking) {
-    copy.reset(master_prefs.DeepCopy());
-    to_serialize = copy.get();
     PrefHashFilter(GetPrefHashStore(false),
                    GetExternalVerificationPrefHashStorePair(),
                    tracking_configuration_, base::Closure(), NULL,
                    reporting_ids_count_, false)
-        .Initialize(copy.get());
+        .Initialize(master_prefs.get());
   }
 
   // This will write out to a single combined file which will be immediately
@@ -199,7 +194,7 @@
   // complete before Chrome can start (as master preferences seed the Local
   // State and Preferences files). This won't trip ThreadIORestrictions as they
   // won't have kicked in yet on the main thread.
-  bool success = serializer.Serialize(*to_serialize);
+  bool success = serializer.Serialize(*master_prefs);
 
   UMA_HISTOGRAM_BOOLEAN("Settings.InitializedFromMasterPrefs", success);
   return success;
diff --git a/chrome/browser/prefs/profile_pref_store_manager.h b/chrome/browser/prefs/profile_pref_store_manager.h
index e1d0898a..4d023665 100644
--- a/chrome/browser/prefs/profile_pref_store_manager.h
+++ b/chrome/browser/prefs/profile_pref_store_manager.h
@@ -92,7 +92,7 @@
   // values in |master_prefs|. Acts synchronously, including blocking IO.
   // Returns true on success.
   bool InitializePrefsFromMasterPrefs(
-      const base::DictionaryValue& master_prefs);
+      std::unique_ptr<base::DictionaryValue> master_prefs);
 
   // Creates a single-file PrefStore as was used in M34 and earlier. Used only
   // for testing migration.
diff --git a/chrome/browser/prefs/profile_pref_store_manager_unittest.cc b/chrome/browser/prefs/profile_pref_store_manager_unittest.cc
index 45230ca..49d3884 100644
--- a/chrome/browser/prefs/profile_pref_store_manager_unittest.cc
+++ b/chrome/browser/prefs/profile_pref_store_manager_unittest.cc
@@ -7,6 +7,7 @@
 #include <stddef.h>
 
 #include <memory>
+#include <utility>
 #include <vector>
 
 #include "base/compiler_specific.h"
@@ -319,10 +320,11 @@
 }
 
 TEST_F(ProfilePrefStoreManagerTest, InitializePrefsFromMasterPrefs) {
-  base::DictionaryValue master_prefs;
-  master_prefs.Set(kTrackedAtomic, new base::StringValue(kFoobar));
-  master_prefs.Set(kProtectedAtomic, new base::StringValue(kHelloWorld));
-  EXPECT_TRUE(manager_->InitializePrefsFromMasterPrefs(master_prefs));
+  auto master_prefs = base::MakeUnique<base::DictionaryValue>();
+  master_prefs->Set(kTrackedAtomic, new base::StringValue(kFoobar));
+  master_prefs->Set(kProtectedAtomic, new base::StringValue(kHelloWorld));
+  EXPECT_TRUE(
+      manager_->InitializePrefsFromMasterPrefs(std::move(master_prefs)));
 
   LoadExistingPrefs();
 
diff --git a/chrome/browser/resources/chromeos/login/arc_terms_of_service.html b/chrome/browser/resources/chromeos/login/arc_terms_of_service.html
index 9f5d77f..e859848 100644
--- a/chrome/browser/resources/chromeos/login/arc_terms_of_service.html
+++ b/chrome/browser/resources/chromeos/login/arc_terms_of_service.html
@@ -8,7 +8,7 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
 
 
-<dom-module name="arc-tos-md">
+<dom-module id="arc-tos-md">
   <template>
     <link rel="stylesheet" href="arc_terms_of_service.css">
     <link rel="stylesheet" href="oobe_dialog_parameters.css">
diff --git a/chrome/browser/resources/chromeos/login/controller-pairing-screen.html b/chrome/browser/resources/chromeos/login/controller-pairing-screen.html
index 2e2446e8..1488d5b6 100644
--- a/chrome/browser/resources/chromeos/login/controller-pairing-screen.html
+++ b/chrome/browser/resources/chromeos/login/controller-pairing-screen.html
@@ -27,7 +27,7 @@
   * connecting - a binary attribute. If set, the list does not respond to the
     user actions and a spinner is shown near selected device.
 -->
-<dom-module name="pairing-device-list">
+<dom-module id="pairing-device-list">
   <link rel="stylesheet" href="pairing_device_list.css">
 
   <iron-iconset-svg name="pairing-device-list-icons">
@@ -75,7 +75,7 @@
   height: 100px;
 }
 -->
-<dom-module name="controller-pairing-page">
+<dom-module id="controller-pairing-page">
   <link rel="stylesheet" href="controller_pairing_page.css">
 
   <template>
@@ -103,7 +103,7 @@
   </template>
 </dom-module>
 
-<dom-module name="controller-pairing-screen">
+<dom-module id="controller-pairing-screen">
   <link rel="stylesheet" href="oobe_screen_controller_pairing.css">
 
   <template>
diff --git a/chrome/browser/resources/chromeos/login/gaia_buttons.html b/chrome/browser/resources/chromeos/login/gaia_buttons.html
index 854dbaac..d53d49b 100644
--- a/chrome/browser/resources/chromeos/login/gaia_buttons.html
+++ b/chrome/browser/resources/chromeos/login/gaia_buttons.html
@@ -50,7 +50,7 @@
   <template>
     <div on-click="onClick_" on-tap="onClick_">
       <paper-icon-button id="iconButton" icon="[[icon]]" disabled="[[disabled]]"
-          aria-label="[[ariaLabel]]">
+          aria-label$="[[ariaLabel]]">
       </paper-icon-button>
     </div>
   </template>
diff --git a/chrome/browser/resources/chromeos/login/gaia_card.html b/chrome/browser/resources/chromeos/login/gaia_card.html
index a8754959..6315118 100644
--- a/chrome/browser/resources/chromeos/login/gaia_card.html
+++ b/chrome/browser/resources/chromeos/login/gaia_card.html
@@ -23,7 +23,7 @@
   Add class |header| to all which you want to go inside blue header.  Similar
   with class |footer|.
 -->
-<dom-module name="gaia-card">
+<dom-module id="gaia-card">
   <link rel="stylesheet" href="gaia_card.css">
 
   <template>
diff --git a/chrome/browser/resources/chromeos/login/gaia_header.html b/chrome/browser/resources/chromeos/login/gaia_header.html
index bdaed2d..6318e22 100644
--- a/chrome/browser/resources/chromeos/login/gaia_header.html
+++ b/chrome/browser/resources/chromeos/login/gaia_header.html
@@ -15,7 +15,7 @@
   Attributes:
    'email' - displayed email.
 -->
-<dom-module name="gaia-header">
+<dom-module id="gaia-header">
   <link rel="stylesheet" href="gaia_header.css">
 
   <template>
diff --git a/chrome/browser/resources/chromeos/login/gaia_input.html b/chrome/browser/resources/chromeos/login/gaia_input.html
index b2562ee..67cac86 100644
--- a/chrome/browser/resources/chromeos/login/gaia_input.html
+++ b/chrome/browser/resources/chromeos/login/gaia_input.html
@@ -34,7 +34,7 @@
     'checkValidity' - returns current validity state of the input form. Updates
                       'isInvalid' at the end.
 -->
-<dom-module name="gaia-input">
+<dom-module id="gaia-input">
   <link rel="stylesheet" href="gaia_input.css">
 
   <template>
diff --git a/chrome/browser/resources/chromeos/login/gaia_input_form.html b/chrome/browser/resources/chromeos/login/gaia_input_form.html
index a6b6ac4..cad99e230 100644
--- a/chrome/browser/resources/chromeos/login/gaia_input_form.html
+++ b/chrome/browser/resources/chromeos/login/gaia_input_form.html
@@ -23,7 +23,7 @@
     'submit' - fired on button click or "Enter" press inside input field.
 
 -->
-<dom-module name="gaia-input-form">
+<dom-module id="gaia-input-form">
   <link rel="stylesheet" href="gaia_input_form.css">
 
   <template>
diff --git a/chrome/browser/resources/chromeos/login/gaia_password_changed.html b/chrome/browser/resources/chromeos/login/gaia_password_changed.html
index 7156743..bcb6d33 100644
--- a/chrome/browser/resources/chromeos/login/gaia_password_changed.html
+++ b/chrome/browser/resources/chromeos/login/gaia_password_changed.html
@@ -39,7 +39,7 @@
     'focus'      - if current card is the first one it focuses password input.
 
 -->
-<dom-module name="gaia-password-changed">
+<dom-module id="gaia-password-changed">
   <link rel="stylesheet" href="gaia_password_changed.css">
 
   <template>
diff --git a/chrome/browser/resources/chromeos/login/host-pairing-screen.html b/chrome/browser/resources/chromeos/login/host-pairing-screen.html
index 7d3eb4ca..1f6adc0 100644
--- a/chrome/browser/resources/chromeos/login/host-pairing-screen.html
+++ b/chrome/browser/resources/chromeos/login/host-pairing-screen.html
@@ -13,7 +13,7 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
 
-<dom-module name="host-pairing-page">
+<dom-module id="host-pairing-page">
 
   <link rel="stylesheet" href="oobe_screen_host_pairing_page.css">
 
@@ -27,7 +27,7 @@
   </template>
 </dom-module>
 
-<dom-module name="host-pairing-screen">
+<dom-module id="host-pairing-screen">
 
   <link rel="stylesheet" href="oobe_screen_host_pairing.css">
 
diff --git a/chrome/browser/resources/chromeos/login/html-echo.html b/chrome/browser/resources/chromeos/login/html-echo.html
index dc9e6dd7..5e0c3ad2 100644
--- a/chrome/browser/resources/chromeos/login/html-echo.html
+++ b/chrome/browser/resources/chromeos/login/html-echo.html
@@ -17,4 +17,4 @@
 
   <span><div>Hello</div></span>
 -->
-<dom-module name="html-echo"></dom-module>
+<dom-module id="html-echo"></dom-module>
diff --git a/chrome/browser/resources/chromeos/login/notification_card.html b/chrome/browser/resources/chromeos/login/notification_card.html
index 641766b..a3dee9f 100644
--- a/chrome/browser/resources/chromeos/login/notification_card.html
+++ b/chrome/browser/resources/chromeos/login/notification_card.html
@@ -26,7 +26,7 @@
     'linkclick' - fired on link click.
 
 -->
-<dom-module name="notification-card">
+<dom-module id="notification-card">
   <link rel="stylesheet" href="notification_card.css">
 
   <template>
diff --git a/chrome/browser/resources/chromeos/login/offline_gaia.html b/chrome/browser/resources/chromeos/login/offline_gaia.html
index 591466a..42ffc89 100644
--- a/chrome/browser/resources/chromeos/login/offline_gaia.html
+++ b/chrome/browser/resources/chromeos/login/offline_gaia.html
@@ -41,7 +41,7 @@
                  screen to password input and shows error that previously
                  entered password is incorrect.
 -->
-<dom-module name="offline-gaia">
+<dom-module id="offline-gaia">
   <link rel="stylesheet" href="offline_gaia.css">
 
   <template>
diff --git a/chrome/browser/resources/chromeos/login/oobe_a11y_option.html b/chrome/browser/resources/chromeos/login/oobe_a11y_option.html
index fcf4d1c..81f5e01 100644
--- a/chrome/browser/resources/chromeos/login/oobe_a11y_option.html
+++ b/chrome/browser/resources/chromeos/login/oobe_a11y_option.html
@@ -2,7 +2,7 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-flex-layout/classes/iron-flex-layout.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html">
 
-<dom-module name="oobe-a11y-option">
+<dom-module id="oobe-a11y-option">
   <template>
     <style>
       :root {
diff --git a/chrome/browser/resources/chromeos/login/oobe_a11y_option.js b/chrome/browser/resources/chromeos/login/oobe_a11y_option.js
index b053ec7..2596b63e 100644
--- a/chrome/browser/resources/chromeos/login/oobe_a11y_option.js
+++ b/chrome/browser/resources/chromeos/login/oobe_a11y_option.js
@@ -22,6 +22,10 @@
 
     /**
      * ARIA-label for the button.
+     *
+     * Note that we are not using "aria-label" property here, because
+     * we want to pass the label value but not actually declare it as an
+     * ARIA property anywhere but the actual target element.
      */
     labelForAria: String,
   },
diff --git a/chrome/browser/resources/chromeos/login/oobe_buttons.html b/chrome/browser/resources/chromeos/login/oobe_buttons.html
index f3d0e7b..df4e93e 100644
--- a/chrome/browser/resources/chromeos/login/oobe_buttons.html
+++ b/chrome/browser/resources/chromeos/login/oobe_buttons.html
@@ -37,13 +37,13 @@
   Attributes:
     'disabled' - button is disabled when the attribute is set.
     'inverse' - makes text white and background blue
-    'aria-label' - accessibility label.
+    'label-for-aria' - accessibility label.
 -->
 <dom-module id="oobe-text-button">
   <link rel="stylesheet" href="oobe_text_button.css">
   <template>
     <paper-button id="textButton" on-tap="onClick_" disabled="[[disabled]]"
-        inverse$="[[inverse]]" aria-label$="[[ariaLabel]]">
+        inverse$="[[inverse]]" aria-label$="[[labelForAria]]">
       <div id="container"
           class="flex layout horizontal center center-justified self-stretch">
         <content></content>
@@ -62,13 +62,13 @@
 
   Attributes:
     'disabled' - button is disabled when the attribute is set.
-    'aria-label' - accessibility label.
+    'label-for-aria' - accessibility label.
 -->
 <dom-module id="oobe-back-button">
   <link rel="stylesheet" href="oobe_nav_button.css">
   <template>
     <paper-button id="button" on-tap="onClick_" disabled="[[disabled]]"
-        aria-label$="[[ariaLabel]]">
+        aria-label$="[[labelForAria]]">
       <div class="flex horizontal layout start center">
         <iron-icon icon="oobe-buttons:arrow-back"></iron-icon>
         <div id="text" i18n-content="back"></div>
@@ -99,12 +99,12 @@
 
   Attributes:
     'icon' - a name of icon from material design set to show on button.
-    'aria-label' - accessibility label.
+    'label-for-aria' - accessibility label.
 -->
 <dom-module id="oobe-welcome-secondary-button">
   <link rel="stylesheet" href="oobe_welcome_secondary_button.css">
   <template>
-    <paper-button id="button" aria-label$="[[ariaLabel]]">
+    <paper-button id="button" aria-label$="[[labelForAria]]">
       <div id="container" class="flex layout vertical center self-stretch">
         <div id="subcontainer"
             class="flex layout horizontal center self-stretch">
diff --git a/chrome/browser/resources/chromeos/login/oobe_buttons.js b/chrome/browser/resources/chromeos/login/oobe_buttons.js
index 53cf9f53..1fc41bb 100644
--- a/chrome/browser/resources/chromeos/login/oobe_buttons.js
+++ b/chrome/browser/resources/chromeos/login/oobe_buttons.js
@@ -10,7 +10,11 @@
 
     inverse: Boolean,
 
-    ariaLabel: String,
+    /* Note that we are not using "aria-label" property here, because
+     * we want to pass the label value but not actually declare it as an
+     * ARIA property anywhere but the actual target element.
+     */
+    labelForAria: String,
   },
 
   focus: function() {
@@ -29,7 +33,11 @@
   properties: {
     disabled: {type: Boolean, value: false, reflectToAttribute: true},
 
-    ariaLabel: String,
+    /* Note that we are not using "aria-label" property here, because
+     * we want to pass the label value but not actually declare it as an
+     * ARIA property anywhere but the actual target element.
+     */
+    labelForAria: String,
   },
 
   focus: function() {
@@ -65,7 +73,11 @@
   properties: {
     icon: String,
 
-    ariaLabel: String
+    /* Note that we are not using "aria-label" property here, because
+     * we want to pass the label value but not actually declare it as an
+     * ARIA property anywhere but the actual target element.
+     */
+    labelForAria: String
   },
 
   focus: function() {
diff --git a/chrome/browser/resources/chromeos/login/oobe_dialog.html b/chrome/browser/resources/chromeos/login/oobe_dialog.html
index e13624190..6f7e0cd8 100644
--- a/chrome/browser/resources/chromeos/login/oobe_dialog.html
+++ b/chrome/browser/resources/chromeos/login/oobe_dialog.html
@@ -37,7 +37,7 @@
   with clases |footer|, |bottom-buttons| and |oobe-icon|. |bottom-buttons| block
   is shown only if |has-buttons| attribute is set.
 -->
-<dom-module name="oobe-dialog">
+<dom-module id="oobe-dialog">
   <template>
     <link rel="stylesheet" href="oobe_dialog_host.css">
     <link rel="stylesheet" href="oobe_dialog.css">
diff --git a/chrome/browser/resources/chromeos/login/oobe_eula.css b/chrome/browser/resources/chromeos/login/oobe_eula.css
index 44b8810..14a1c24 100644
--- a/chrome/browser/resources/chromeos/login/oobe_eula.css
+++ b/chrome/browser/resources/chromeos/login/oobe_eula.css
@@ -14,21 +14,24 @@
 }
 
 #installationSettings {
-  padding-top: 31px; /* = 44 - font size */
+  -webkit-margin-start: 20px;
+  margin-top: 31px; /* = 44 - font size */
 }
 
 #logging {
+  -webkit-margin-start: 20px;
   color: rgba(0, 0, 0, 0.54);
-  padding-top: 21px; /* = 36 - font size */
+  margin-bottom: 20px;
+  margin-top: 23px; /* = 36 - font size */
 }
 
 #usageStats {
-  --paper-checkbox-size: 20px;
+  --paper-checkbox-size: 16px;
   --paper-checkbox-checked-color: rgb(66, 133, 244); /* #4285f4 */
-  /* End padding must be greater than --paper-checkbox-label-spacing */
-  -webkit-padding-end: 16px;
-  max-width: 550px;
-  padding-bottom: 20px;
+}
+
+#usageStatsLabelContainer label {
+  color: rgba(0, 0, 0, .54);
 }
 
 .bottom-buttons {
diff --git a/chrome/browser/resources/chromeos/login/oobe_eula.html b/chrome/browser/resources/chromeos/login/oobe_eula.html
index 12958f59..67ed5320 100644
--- a/chrome/browser/resources/chromeos/login/oobe_eula.html
+++ b/chrome/browser/resources/chromeos/login/oobe_eula.html
@@ -23,12 +23,12 @@
   </svg>
 </iron-iconset-svg>
 
-<dom-module name="oobe-eula-md">
+<dom-module id="oobe-eula-md">
   <template>
     <link rel="stylesheet" href="oobe_eula.css">
     <link rel="stylesheet" href="oobe_dialog_parameters.css">
     <oobe-dialog id="eulaLoadingDialog" hidden="[[!eulaLoadingScreenShown]]"
-        role="dialog" aria-label="$i18n{termsOfServiceLoading}"
+        role="dialog" aria-label$="$i18n{termsOfServiceLoading}"
         has-buttons>
       <iron-icon icon="oobe-eula:googleg" class="oobe-icon"></iron-icon>
       <div class="header">
@@ -36,7 +36,7 @@
       </div>
     </oobe-dialog>
     <oobe-dialog id="eulaDialog" hidden="[[eulaLoadingScreenShown]]"
-        role="dialog" aria-label="$i18n{oobeEulaSectionTitle}"
+        role="dialog" aria-label$="$i18n{oobeEulaSectionTitle}"
         has-buttons>
       <iron-icon icon="oobe-eula:googleg" class="oobe-icon"></iron-icon>
       <div class="header">
@@ -45,22 +45,24 @@
       <div class="footer flex layout vertical">
         <iframe id="crosEulaFrame" src="chrome://terms"
             role="document" class="flex focus-on-show"
-            aria-label="$i18n{oobeEulaIframeLabel}"
+            aria-label$="$i18n{oobeEulaIframeLabel}"
             on-load="onFrameLoad_">
         </iframe>
         <a id="installationSettings" href="#"
             on-tap="onInstallationSettingsClicked_"
             i18n-content="eulaSystemInstallationSettings">
         </a>
-        <div id="logging">
+        <div id="logging" class="layout horizontal">
           <paper-checkbox aria-labelledby="usage-stats-label" id="usageStats"
               checked="{{usageStatsChecked}}" on-change="onUsageChanged_">
+          </paper-checkbox>
+          <div id="usageStatsLabelContainer">
             <label id="usage-stats-label" i18n-content="checkboxLogging">
             </label>
             <a id="" href="#" i18n-content="learnMore"
                 on-tap="onUsageStatsHelpLinkClicked_">
             </a>
-          </paper-checkbox>
+          </div>
         </div>
       </div>
       <div class="bottom-buttons flex layout horizontal">
diff --git a/chrome/browser/resources/chromeos/login/oobe_hid_detection.html b/chrome/browser/resources/chromeos/login/oobe_hid_detection.html
index f37d39ef..acb628c 100644
--- a/chrome/browser/resources/chromeos/login/oobe_hid_detection.html
+++ b/chrome/browser/resources/chromeos/login/oobe_hid_detection.html
@@ -12,7 +12,7 @@
   </svg>
 </iron-iconset-svg>
 
-<dom-module name="oobe-hid-detection-md">
+<dom-module id="oobe-hid-detection-md">
   <template>
     <link rel="stylesheet" href="oobe_hid_detection.css">
     <link rel="stylesheet" href="oobe_dialog_parameters.css">
diff --git a/chrome/browser/resources/chromeos/login/oobe_i18n_dropdown.js b/chrome/browser/resources/chromeos/login/oobe_i18n_dropdown.js
index 7e7253a..ff5835a2 100644
--- a/chrome/browser/resources/chromeos/login/oobe_i18n_dropdown.js
+++ b/chrome/browser/resources/chromeos/login/oobe_i18n_dropdown.js
@@ -29,6 +29,10 @@
 
     /**
      * ARIA-label for the selection menu.
+     *
+     * Note that we are not using "aria-label" property here, because
+     * we want to pass the label value but not actually declare it as an
+     * ARIA property anywhere but the actual target element.
      */
     labelForAria: String,
   },
diff --git a/chrome/browser/resources/chromeos/login/oobe_update.html b/chrome/browser/resources/chromeos/login/oobe_update.html
index d7ea1d4..d723bf7 100644
--- a/chrome/browser/resources/chromeos/login/oobe_update.html
+++ b/chrome/browser/resources/chromeos/login/oobe_update.html
@@ -23,7 +23,7 @@
   </svg>
 </iron-iconset-svg>
 
-<dom-module name="oobe-update-md">
+<dom-module id="oobe-update-md">
   <template>
     <link rel="stylesheet" href="oobe_update.css">
     <link rel="stylesheet" href="oobe_dialog_parameters.css">
diff --git a/chrome/browser/resources/chromeos/login/oobe_welcome.html b/chrome/browser/resources/chromeos/login/oobe_welcome.html
index 52ff0bb..e905a5b 100644
--- a/chrome/browser/resources/chromeos/login/oobe_welcome.html
+++ b/chrome/browser/resources/chromeos/login/oobe_welcome.html
@@ -52,13 +52,13 @@
   </svg>
 </iron-iconset-svg>
 
-<dom-module name="oobe-welcome-md">
+<dom-module id="oobe-welcome-md">
   <template>
     <link rel="stylesheet" href="oobe_dialog_host.css">
     <link rel="stylesheet" href="oobe_welcome.css">
     <link rel="stylesheet" href="oobe_dialog_parameters.css">
     <oobe-welcome-dialog id="welcomeScreen" role="dialog"
-        aria-label="[[formatMessage_('networkScreenGreeting')]]"
+        i18n-values="aria-label:networkScreenGreeting"
         current-language="[[currentLanguage]]"
         on-language-button-clicked="onWelcomeSelectLanguageButtonClicked_"
         on-accessibility-button-clicked="onWelcomeAccessibilityButtonClicked_"
@@ -69,7 +69,7 @@
         >
     </oobe-welcome-dialog>
     <oobe-dialog id="languageScreen" role="dialog" hidden has-buttons
-        aria-label="[[formatMessage_('languageSectionTitle')]]">
+        i18n-values="aria-label:languageSectionTitle">
       <iron-icon icon="icons:language" class="oobe-icon"></iron-icon>
       <div class="header">
         <h1 class="title" i18n-content="languageSectionTitle"></h1>
@@ -83,7 +83,8 @@
             </div>
             <oobe-i18n-dropdown id="languageSelect" items="[[languages]]"
                 on-select-item="onLanguageSelected_"
-                class="focus-on-show">
+                class="focus-on-show"
+                i18n-values="label-for-aria:languageDropdownLabel">
             </oobe-i18n-dropdown>
           </div>
           <div id="keyboardDropdownContainer"
@@ -92,7 +93,8 @@
                 i18n-content="keyboardDropdownTitle">
             </div>
             <oobe-i18n-dropdown id="keyboardSelect" items="[[keyboards]]"
-                on-select-item="onKeyboardSelected_">
+                on-select-item="onKeyboardSelected_"
+                i18n-values="label-for-aria:keyboardDropdownLabel">
             </oobe-i18n-dropdown>
           </div>
         </template>
@@ -104,7 +106,7 @@
       </div>
     </oobe-dialog>
     <oobe-dialog id="accessibilityScreen" role="dialog" hidden has-buttons
-        aria-label="[[formatMessage_('accessibilitySectionTitle')]]">
+        i18n-values="aria-label:accessibilitySectionTitle">
       <iron-icon icon="icons:accessibility" class="oobe-icon"></iron-icon>
       <div class="header">
         <h1 class="title" i18n-content="accessibilitySectionTitle"></h1>
@@ -114,7 +116,7 @@
         <oobe-a11y-option checked="[[a11yStatus.spokenFeedbackEnabled]]"
             on-change="onA11yOptionChanged_"
             chrome-message="enableSpokenFeedback"
-            label-for-aria="[[formatMessage_('spokenFeedbackOption')]]"
+            i18n-values="label-for-aria:spokenFeedbackOption"
             class="focus-on-show">
           <span class="title" i18n-content="spokenFeedbackOption"></span>
           <span class="checked-value" i18n-content="spokenFeedbackOptionOn">
@@ -125,7 +127,7 @@
         <oobe-a11y-option checked="[[a11yStatus.largeCursorEnabled]]"
             on-change="onA11yOptionChanged_"
             chrome-message="enableLargeCursor"
-            label-for-aria="[[formatMessage_('largeCursorOption')]]">
+            i18n-values="label-for-aria:largeCursorOption">
           <span class="title" i18n-content="largeCursorOption"></span>
           <span class="checked-value" i18n-content="largeCursorOptionOn">
           </span>
@@ -135,7 +137,7 @@
         <oobe-a11y-option checked="[[a11yStatus.highContrastEnabled]]"
             on-change="onA11yOptionChanged_"
             chrome-message="enableHighContrast"
-            label-for-aria="[[formatMessage_('highContrastOption')]]">
+            i18n-values="label-for-aria:highContrastOption">
           <span class="title" i18n-content="highContrastOption"></span>
           <span class="checked-value" i18n-content="highContrastOptionOn">
           </span>
@@ -145,7 +147,7 @@
         <oobe-a11y-option checked="[[a11yStatus.screenMagnifierEnabled]]"
             on-change="onA11yOptionChanged_"
             chrome-message="enableScreenMagnifier"
-            label-for-aria="[[formatMessage_('screenMagnifierOption')]]">
+            i18n-values="label-for-aria:screenMagnifierOption">
           <span class="title" i18n-content="screenMagnifierOption"></span>
           <span class="checked-value" i18n-content="screenMagnifierOptionOn">
           </span>
@@ -155,7 +157,7 @@
         <oobe-a11y-option checked="[[a11yStatus.virtualKeyboardEnabled]]"
             on-change="onA11yOptionChanged_"
             chrome-message="enableVirtualKeyboard"
-            label-for-aria="[[formatMessage_('virtualKeyboardOption')]]">
+            i18n-values="label-for-aria:virtualKeyboardOption">
           <span class="title" i18n-content="virtualKeyboardOption"></span>
           <span class="checked-value" i18n-content="virtualKeyboardOptionOn">
           </span>
@@ -170,7 +172,7 @@
       </div>
     </oobe-dialog>
     <oobe-dialog id="timezoneScreen" role="dialog" hidden has-buttons
-        aria-label="[[formatMessage_('timezoneSectionTitle')]]">
+        i18n-values="aria-label:timezoneSectionTitle">
       <iron-icon icon="oobe-welcome-64:timezone" class="oobe-icon"></iron-icon>
       <div class="header">
         <h1 class="title" i18n-content="timezoneSectionTitle"></h1>
@@ -182,7 +184,7 @@
           </div>
           <oobe-i18n-dropdown id="timezoneSelect" items="[[timezones]]"
               on-select-item="onTimezoneSelected_"
-              label-for-aria="[[formatMessage_('timezoneDropdownTitle')]]"
+              i18n-values="label-for-aria:timezoneDropdownLabel"
               class="focus-on-show">
           </oobe-i18n-dropdown>
         </div>
@@ -194,7 +196,7 @@
       </div>
     </oobe-dialog>
     <oobe-dialog id="networkSelectionScreen" role="dialog" hidden has-buttons
-        aria-label="[[formatMessage_('networkSectionTitle')]]"
+        i18n-values="aria-label:networkSectionTitle"
         on-show-dialog="onNetworkSelectionScreenShown_">
       <iron-icon icon="oobe-welcome:wifi" class="oobe-icon"></iron-icon>
       <div class="header">
diff --git a/chrome/browser/resources/chromeos/login/oobe_welcome.js b/chrome/browser/resources/chromeos/login/oobe_welcome.js
index adfa836..68a45a1 100644
--- a/chrome/browser/resources/chromeos/login/oobe_welcome.js
+++ b/chrome/browser/resources/chromeos/login/oobe_welcome.js
@@ -465,14 +465,4 @@
 
     this.screen.onTimezoneSelected_(item.value);
   },
-
-  /**
-    * This function formats message for labels.
-    * @param String label i18n string ID.
-    * @param String parameter i18n string parameter.
-    * @private
-    */
-  formatMessage_: function(label, parameter) {
-    return loadTimeData.getStringF(label, parameter);
-  },
 });
diff --git a/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.html b/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.html
index 7105dd76..11b374c 100644
--- a/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.html
+++ b/chrome/browser/resources/chromeos/login/oobe_welcome_dialog.html
@@ -8,7 +8,7 @@
 <!--
   OOBE Welcome screen
 -->
-<dom-module name="oobe-welcome-dialog">
+<dom-module id="oobe-welcome-dialog">
   <template>
     <link rel="stylesheet" href="oobe_dialog_host.css">
     <link rel="stylesheet" href="oobe_welcome_dialog.css">
@@ -27,7 +27,7 @@
         <div id="buttons" class="layout horizontal center">
           <oobe-welcome-secondary-button id="languageSelectionButton"
               icon="icons:language" on-tap="onLanguageClicked_"
-              aria-label="[[formatMessage_('languageButtonLabel',
+              label-for-aria$="[[formatMessage_('languageButtonLabel',
                   currentLanguage)]]">
             <div>[[currentLanguage]]</div>
           </oobe-welcome-secondary-button>
diff --git a/chrome/browser/resources/chromeos/login/saml_confirm_password.html b/chrome/browser/resources/chromeos/login/saml_confirm_password.html
index e9b755e..cc4b83b8 100644
--- a/chrome/browser/resources/chromeos/login/saml_confirm_password.html
+++ b/chrome/browser/resources/chromeos/login/saml_confirm_password.html
@@ -37,7 +37,7 @@
                    empties password field and enables buttons.
     'focus'      - If the current card is the first one, focuses password input.
 -->
-<dom-module name="saml-confirm-password">
+<dom-module id="saml-confirm-password">
   <link rel="stylesheet" href="saml_confirm_password.css">
 
   <template>
diff --git a/chrome/browser/resources/chromeos/login/saml_interstitial.html b/chrome/browser/resources/chromeos/login/saml_interstitial.html
index 0fc1c268..a806dd9 100644
--- a/chrome/browser/resources/chromeos/login/saml_interstitial.html
+++ b/chrome/browser/resources/chromeos/login/saml_interstitial.html
@@ -26,7 +26,7 @@
                                    a differnt account link. GAIA Minute Maid
                                    screen will be shown.
 -->
-<dom-module name="saml-interstitial">
+<dom-module id="saml-interstitial">
 
 <template>
   <style>
diff --git a/chrome/browser/resources/chromeos/login/throbber_notice.html b/chrome/browser/resources/chromeos/login/throbber_notice.html
index 397f4cd..9bd1710 100644
--- a/chrome/browser/resources/chromeos/login/throbber_notice.html
+++ b/chrome/browser/resources/chromeos/login/throbber_notice.html
@@ -6,7 +6,7 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-styles/color.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/polymer/polymer.html">
 
-<dom-module name="throbber-notice">
+<dom-module id="throbber-notice">
   <link rel="stylesheet" href="throbber_notice.css">
   <template>
     <paper-spinner dir="ltr" active></paper-spinner>
diff --git a/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.html b/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.html
index bc00a605..0c98c25 100644
--- a/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.html
+++ b/chrome/browser/resources/chromeos/login/unrecoverable_cryptohome_error_card.html
@@ -14,7 +14,7 @@
   Events:
     'done' - fired when user clicks on continue button.
 -->
-<dom-module name="unrecoverable-cryptohome-error-card">
+<dom-module id="unrecoverable-cryptohome-error-card">
   <link rel="stylesheet" href="unrecoverable_cryptohome_error_card.css">
 
   <template>
diff --git a/chrome/browser/resources/local_ntp/OWNERS b/chrome/browser/resources/local_ntp/OWNERS
index 98b64ed..aca0124f 100644
--- a/chrome/browser/resources/local_ntp/OWNERS
+++ b/chrome/browser/resources/local_ntp/OWNERS
@@ -5,3 +5,6 @@
 fserb@chromium.org
 huangs@chromium.org
 treib@chromium.org
+
+# TEAM: ntp-dev@chromium.org
+# COMPONENT: UI>Browser>NewTabPage
diff --git a/chrome/browser/resources/md_feedback/feedback_container.html b/chrome/browser/resources/md_feedback/feedback_container.html
index 6c004710..2e88d7f 100644
--- a/chrome/browser/resources/md_feedback/feedback_container.html
+++ b/chrome/browser/resources/md_feedback/feedback_container.html
@@ -3,7 +3,7 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-textarea.html">
-<dom-module name="feedback-container">
+<dom-module id="feedback-container">
   <template>
     <style>
       #additional-info {
@@ -70,4 +70,4 @@
     </div>
   </template>
   <script src="feedback_container.js"></script>
-</dom-module>
\ No newline at end of file
+</dom-module>
diff --git a/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.html b/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.html
index e66899f9..1087a9a 100644
--- a/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.html
+++ b/chrome/browser/resources/media_router/elements/issue_banner/issue_banner.html
@@ -2,7 +2,7 @@
 <link rel="import" href="chrome://resources/html/i18n_behavior.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
 <link rel="import" href="../../icons/media_router_icons.html">
-<dom-module name="issue-banner">
+<dom-module id="issue-banner">
   <link rel="import" type="css" href="../../media_router_common.css">
   <link rel="import" type="css" href="issue_banner.css">
   <template>
diff --git a/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.html b/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.html
index d4d69a7..7a0603a 100644
--- a/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.html
+++ b/chrome/browser/resources/media_router/elements/media_router_header/media_router_header.html
@@ -2,7 +2,7 @@
 <link rel="import" href="chrome://resources/html/i18n_behavior.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-icon-button/paper-icon-button.html">
 <link rel="import" href="../../icons/media_router_icons.html">
-<dom-module name="media-router-header">
+<dom-module id="media-router-header">
   <link rel="import" type="css" href="../../media_router_common.css">
   <link rel="import" type="css" href="media_router_header.css">
   <template>
diff --git a/chrome/browser/resources/settings/controls/compiled_resources2.gyp b/chrome/browser/resources/settings/controls/compiled_resources2.gyp
index a538d256..66451b2 100644
--- a/chrome/browser/resources/settings/controls/compiled_resources2.gyp
+++ b/chrome/browser/resources/settings/controls/compiled_resources2.gyp
@@ -6,7 +6,6 @@
     {
       'target_name': 'controlled_button',
       'dependencies': [
-        '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_indicator_behavior',
         '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_pref_behavior',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert',
         'pref_control_behavior',
@@ -16,7 +15,6 @@
     {
       'target_name': 'controlled_radio_button',
       'dependencies': [
-        '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_pref_behavior',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert',
         '<(EXTERNS_GYP):settings_private',
         '../prefs/compiled_resources2.gyp:pref_util',
@@ -44,7 +42,6 @@
       'target_name': 'settings_boolean_control_behavior',
       'dependencies': [
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert',
-        '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_indicator_behavior',
         '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_pref_behavior',
         '../prefs/compiled_resources2.gyp:prefs_types',
         'pref_control_behavior',
@@ -85,7 +82,6 @@
     {
       'target_name': 'settings_radio_group',
       'dependencies': [
-        '<(DEPTH)/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp:cr_policy_pref_behavior',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:assert',
         '<(DEPTH)/ui/webui/resources/js/compiled_resources2.gyp:cr',
         '<(EXTERNS_GYP):settings_private',
diff --git a/chrome/browser/resources/settings/controls/controlled_button.html b/chrome/browser/resources/settings/controls/controlled_button.html
index 7f4e69d4..b053b26 100644
--- a/chrome/browser/resources/settings/controls/controlled_button.html
+++ b/chrome/browser/resources/settings/controls/controlled_button.html
@@ -1,7 +1,6 @@
 <link rel="import" href="chrome://resources/html/assert.html">
 <link rel="import" href="chrome://resources/html/polymer.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-button/paper-button.html">
-<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_indicator_behavior.html">
 <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_behavior.html">
 <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html">
 <link rel="import" href="pref_control_behavior.html">
@@ -43,7 +42,7 @@
       <content></content>
     </paper-button>
 
-    <template is="dom-if" if="[[showIndicator_(pref)]]" restamp>
+    <template is="dom-if" if="[[hasPrefPolicyIndicator(pref.*)]]" restamp>
       <cr-policy-pref-indicator pref="[[pref]]" on-tap="onIndicatorTap_">
       </cr-policy-pref-indicator>
     </template>
diff --git a/chrome/browser/resources/settings/controls/controlled_button.js b/chrome/browser/resources/settings/controls/controlled_button.js
index d1b9723..a1188763 100644
--- a/chrome/browser/resources/settings/controls/controlled_button.js
+++ b/chrome/browser/resources/settings/controls/controlled_button.js
@@ -6,7 +6,6 @@
   is: 'controlled-button',
 
   behaviors: [
-    CrPolicyIndicatorBehavior,
     CrPolicyPrefBehavior,
     PrefControlBehavior,
   ],
@@ -43,16 +42,4 @@
     e.preventDefault();
     e.stopPropagation();
   },
-
-  /**
-   * @param {!chrome.settingsPrivate.PrefObject} pref
-   * @return {boolean} Whether to show a controlled by indicator.
-   * @private
-   */
-  showIndicator_: function(pref) {
-    if (!pref.controlledBy || !pref.enforcement)
-      return false;
-    var indicator = this.getIndicatorType(pref.controlledBy, pref.enforcement);
-    return this.isIndicatorVisible(indicator);
-  },
 });
diff --git a/chrome/browser/resources/settings/controls/controlled_radio_button.html b/chrome/browser/resources/settings/controls/controlled_radio_button.html
index 7631de20..90c000b 100644
--- a/chrome/browser/resources/settings/controls/controlled_radio_button.html
+++ b/chrome/browser/resources/settings/controls/controlled_radio_button.html
@@ -37,7 +37,7 @@
       <content></content>
     </paper-radio-button>
 
-    <template is="dom-if" if="[[showIndicator_(controlled_, name, pref)]]">
+    <template is="dom-if" if="[[showIndicator_(controlled_, name, pref.*)]]">
       <cr-policy-pref-indicator pref="[[pref]]" on-tap="onIndicatorTap_">
       </cr-policy-pref-indicator>
     </template>
diff --git a/chrome/browser/resources/settings/controls/controlled_radio_button.js b/chrome/browser/resources/settings/controls/controlled_radio_button.js
index f6221e95..39e5fbf 100644
--- a/chrome/browser/resources/settings/controls/controlled_radio_button.js
+++ b/chrome/browser/resources/settings/controls/controlled_radio_button.js
@@ -36,12 +36,12 @@
   /**
    * @param {boolean} controlled
    * @param {string} name
-   * @param {chrome.settingsPrivate.PrefObject} pref
    * @return {boolean}
    * @private
    */
-  showIndicator_: function(controlled, name, pref) {
-    return controlled && name == Settings.PrefUtil.prefToString(pref);
+  showIndicator_: function(controlled, name) {
+    return controlled &&
+        name == Settings.PrefUtil.prefToString(assert(this.pref));
   },
 
   /**
diff --git a/chrome/browser/resources/settings/controls/settings_boolean_control_behavior.html b/chrome/browser/resources/settings/controls/settings_boolean_control_behavior.html
index 2311a10..f4d2a6f 100644
--- a/chrome/browser/resources/settings/controls/settings_boolean_control_behavior.html
+++ b/chrome/browser/resources/settings/controls/settings_boolean_control_behavior.html
@@ -1,6 +1,5 @@
 <link rel="import" href="chrome://resources/html/assert.html">
 <link rel="import" href="chrome://resources/html/polymer.html">
 <link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_behavior.html">
-<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html">
 <link rel="import" href="pref_control_behavior.html">
 <script src="settings_boolean_control_behavior.js"></script>
diff --git a/chrome/browser/resources/settings/controls/settings_boolean_control_behavior.js b/chrome/browser/resources/settings/controls/settings_boolean_control_behavior.js
index 85614f9..b22619a 100644
--- a/chrome/browser/resources/settings/controls/settings_boolean_control_behavior.js
+++ b/chrome/browser/resources/settings/controls/settings_boolean_control_behavior.js
@@ -124,7 +124,7 @@
    * @private
    */
   controlDisabled_: function() {
-    return this.disabled || this.isPrefPolicyControlled(assert(this.pref));
+    return this.disabled || this.isPrefPolicyControlled();
   },
 };
 
diff --git a/chrome/browser/resources/settings/controls/settings_checkbox.html b/chrome/browser/resources/settings/controls/settings_checkbox.html
index 34284a0..4b31374 100644
--- a/chrome/browser/resources/settings/controls/settings_checkbox.html
+++ b/chrome/browser/resources/settings/controls/settings_checkbox.html
@@ -1,3 +1,4 @@
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html">
 <link rel="import" href="chrome://resources/html/polymer.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-checkbox/paper-checkbox.html">
 <link rel="import" href="settings_boolean_control_behavior.html">
@@ -32,7 +33,7 @@
     <div id="outerRow" noSubLabel$="[[!subLabel]]">
       <paper-checkbox id="checkbox" checked="{{checked}}"
           on-change="notifyChangedByUserInteraction"
-          disabled="[[controlDisabled_(disabled, pref)]]">
+          disabled="[[controlDisabled_(disabled, pref.*)]]">
         <div>[[label]] <content></content></div>
         <div class="secondary">[[subLabel]]</div>
       </paper-checkbox>
diff --git a/chrome/browser/resources/settings/controls/settings_input.html b/chrome/browser/resources/settings/controls/settings_input.html
index f6162561..51bf0ee 100644
--- a/chrome/browser/resources/settings/controls/settings_input.html
+++ b/chrome/browser/resources/settings/controls/settings_input.html
@@ -19,7 +19,7 @@
           error-message="[[errorMessage]]" label="[[label]]"
           no-label-float="[[noLabelFloat]]" pattern="[[pattern]]"
           readonly$="[[readonly]]" required="[[required]]" type="[[type]]"
-          on-change="onChange_" disabled="[[isDisabled_(disabled, pref)]]"
+          on-change="onChange_" disabled="[[isDisabled_(disabled, pref.*)]]"
           stop-keyboard-event-propagation$="[[stopKeyboardEventPropagation]]"
           tabindex$="[[getTabindex_(canTab)]]">
       </paper-input>
diff --git a/chrome/browser/resources/settings/controls/settings_input.js b/chrome/browser/resources/settings/controls/settings_input.js
index 2652db17..0bee823 100644
--- a/chrome/browser/resources/settings/controls/settings_input.js
+++ b/chrome/browser/resources/settings/controls/settings_input.js
@@ -119,11 +119,10 @@
 
   /**
    * @param {boolean} disabled
-   * @param {!chrome.settingsPrivate.PrefObject} pref
    * @return {boolean} Whether the element should be disabled.
    * @private
    */
-  isDisabled_: function(disabled, pref) {
-    return disabled || this.isPrefPolicyControlled(pref);
+  isDisabled_: function(disabled) {
+    return disabled || this.isPrefPolicyControlled();
   },
 });
diff --git a/chrome/browser/resources/settings/controls/settings_toggle_button.html b/chrome/browser/resources/settings/controls/settings_toggle_button.html
index c20a033c..22e2bb5 100644
--- a/chrome/browser/resources/settings/controls/settings_toggle_button.html
+++ b/chrome/browser/resources/settings/controls/settings_toggle_button.html
@@ -1,3 +1,4 @@
+<link rel="import" href="chrome://resources/cr_elements/policy/cr_policy_pref_indicator.html">
 <link rel="import" href="chrome://resources/html/polymer.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-toggle-button/paper-toggle-button.html">
 <link rel="import" href="settings_boolean_control_behavior.html">
@@ -38,7 +39,7 @@
     </style>
     <div id="outerRow" noSubLabel$="[[!subLabel]]">
       <div class="flex" on-tap="onLabelWrapperTap_"
-          actionable$="[[!controlDisabled_(disabled, pref)]]">
+          actionable$="[[!controlDisabled_(disabled, pref.*)]]">
         <div id="label" class="label">
           [[label]]
         </div>
diff --git a/chrome/browser/resources/settings/internet_page/network_property_list.html b/chrome/browser/resources/settings/internet_page/network_property_list.html
index 8dbe334..a751c49 100644
--- a/chrome/browser/resources/settings/internet_page/network_property_list.html
+++ b/chrome/browser/resources/settings/internet_page/network_property_list.html
@@ -6,7 +6,7 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-input/paper-input-container.html">
 <link rel="import" href="internet_shared_css.html">
 
-<dom-module name="network-property-list">
+<dom-module id="network-property-list">
   <template>
     <style include="internet-shared">
       paper-input-container {
diff --git a/chrome/browser/resources/settings/internet_page/network_summary_item.html b/chrome/browser/resources/settings/internet_page/network_summary_item.html
index ee3e90f..b869f2f4 100644
--- a/chrome/browser/resources/settings/internet_page/network_summary_item.html
+++ b/chrome/browser/resources/settings/internet_page/network_summary_item.html
@@ -14,7 +14,7 @@
 <link rel="import" href="../settings_shared_css.html">
 <link rel="import" href="network_siminfo.html">
 
-<dom-module name="network-summary-item">
+<dom-module id="network-summary-item">
   <template>
     <style include="settings-shared action-link">
       paper-spinner {
diff --git a/chrome/browser/resources/settings/languages_page/languages_page.html b/chrome/browser/resources/settings/languages_page/languages_page.html
index 2271af5..acf1628 100644
--- a/chrome/browser/resources/settings/languages_page/languages_page.html
+++ b/chrome/browser/resources/settings/languages_page/languages_page.html
@@ -186,6 +186,12 @@
               </a>
             </div>
           </div>
+          <div class="settings-box">
+            <settings-toggle-button class="start"
+                pref="{{prefs.settings.language.ime_menu_activated}}"
+                label="$i18n{showImeMenu}">
+            </settings-toggle-button>
+          </div>
         </iron-collapse>
 </if>
 <if expr="not is_macosx">
diff --git a/chrome/browser/rlz/chrome_rlz_tracker_delegate.cc b/chrome/browser/rlz/chrome_rlz_tracker_delegate.cc
index 2988886a..0da9621f 100644
--- a/chrome/browser/rlz/chrome_rlz_tracker_delegate.cc
+++ b/chrome/browser/rlz/chrome_rlz_tracker_delegate.cc
@@ -18,6 +18,7 @@
 #include "chrome/common/pref_names.h"
 #include "components/google/core/browser/google_util.h"
 #include "components/omnibox/browser/omnibox_log.h"
+#include "components/pref_registry/pref_registry_syncable.h"
 #include "components/prefs/pref_service.h"
 #include "components/search_engines/template_url.h"
 #include "components/search_engines/template_url_service.h"
@@ -29,6 +30,7 @@
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_source.h"
 #include "content/public/common/content_switches.h"
+#include "rlz/features/features.h"
 
 #if defined(OS_WIN)
 #include "chrome/installer/util/google_update_settings.h"
@@ -41,6 +43,14 @@
 }
 
 // static
+void ChromeRLZTrackerDelegate::RegisterProfilePrefs(
+    user_prefs::PrefRegistrySyncable* registry) {
+#if BUILDFLAG(ENABLE_RLZ)
+  registry->RegisterIntegerPref(prefs::kRlzPingDelaySeconds, 90);
+#endif
+}
+
+// static
 bool ChromeRLZTrackerDelegate::IsGoogleDefaultSearch(Profile* profile) {
   bool is_google_default_search = false;
   TemplateURLService* template_url_service =
diff --git a/chrome/browser/rlz/chrome_rlz_tracker_delegate.h b/chrome/browser/rlz/chrome_rlz_tracker_delegate.h
index 1fdc71a..1fe2eaa 100644
--- a/chrome/browser/rlz/chrome_rlz_tracker_delegate.h
+++ b/chrome/browser/rlz/chrome_rlz_tracker_delegate.h
@@ -14,6 +14,10 @@
 
 class Profile;
 
+namespace user_prefs {
+class PrefRegistrySyncable;
+}
+
 // ChromeRLZTrackerDelegate implements RLZTrackerDelegate abstract interface
 // and provides access to Chrome features.
 class ChromeRLZTrackerDelegate : public rlz::RLZTrackerDelegate,
@@ -22,6 +26,8 @@
   ChromeRLZTrackerDelegate();
   ~ChromeRLZTrackerDelegate() override;
 
+  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
+
   static bool IsGoogleDefaultSearch(Profile* profile);
   static bool IsGoogleHomepage(Profile* profile);
   static bool IsGoogleInStartpages(Profile* profile);
diff --git a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc
index 530300f8..c662506 100644
--- a/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc
+++ b/chrome/browser/safe_browsing/safe_browsing_navigation_observer.cc
@@ -177,7 +177,6 @@
   // We should have already seen this navigation_handle in DidStartNavigation.
   if (navigation_handle_map_.find(navigation_handle) ==
       navigation_handle_map_.end()) {
-    NOTREACHED();
     return;
   }
   NavigationEvent* nav_event = navigation_handle_map_[navigation_handle].get();
@@ -191,7 +190,6 @@
     content::NavigationHandle* navigation_handle) {
   if (navigation_handle_map_.find(navigation_handle) ==
       navigation_handle_map_.end()) {
-    NOTREACHED();
     return;
   }
 
diff --git a/chrome/browser/search/suggestions/OWNERS b/chrome/browser/search/suggestions/OWNERS
index f5f61960..28c1796 100644
--- a/chrome/browser/search/suggestions/OWNERS
+++ b/chrome/browser/search/suggestions/OWNERS
@@ -1,2 +1,5 @@
 mathp@chromium.org
 treib@chromium.org
+
+# TEAM: ntp-dev@chromium.org
+# COMPONENT: UI>Browser>NewTabPage
diff --git a/chrome/browser/thumbnails/simple_thumbnail_crop.cc b/chrome/browser/thumbnails/simple_thumbnail_crop.cc
index 5b12db4..4c13ea6 100644
--- a/chrome/browser/thumbnails/simple_thumbnail_crop.cc
+++ b/chrome/browser/thumbnails/simple_thumbnail_crop.cc
@@ -75,7 +75,7 @@
   return clipped_bitmap;
 }
 
-// RenderWidgetHost::CopyFromBackingStore can be costly especially when it is
+// RenderWidgetHostView::CopyFromSurface() can be costly especially when it is
 // necessary to read back the web contents image data from GPU. As the cost is
 // roughly proportional to the number of the copied pixels, the size of the
 // copied pixels should be as small as possible.
diff --git a/chrome/browser/thumbnails/thumbnail_tab_helper.cc b/chrome/browser/thumbnails/thumbnail_tab_helper.cc
index bfc5005..b710d4cc 100644
--- a/chrome/browser/thumbnails/thumbnail_tab_helper.cc
+++ b/chrome/browser/thumbnails/thumbnail_tab_helper.cc
@@ -150,6 +150,9 @@
     return;
   }
 
+  // TODO(miu): This is the wrong size. It's the size of the view on-screen, and
+  // not the rendering size of the view. This will be replaced with the view's
+  // actual rendering size in a later change. http://crbug.com/73362
   gfx::Rect copy_rect = gfx::Rect(view->GetViewBounds().size());
   // Clip the pixels that will commonly hold a scrollbar, which looks bad in
   // thumbnails.
@@ -175,13 +178,10 @@
       scale_factor,
       &copy_rect,
       &thumbnailing_context_->requested_copy_size);
-  render_widget_host->CopyFromBackingStore(
-      copy_rect,
-      thumbnailing_context_->requested_copy_size,
-      base::Bind(&ThumbnailTabHelper::ProcessCapturedBitmap,
-                 weak_factory_.GetWeakPtr(),
-                 algorithm),
-      kN32_SkColorType);
+  view->CopyFromSurface(copy_rect, thumbnailing_context_->requested_copy_size,
+                        base::Bind(&ThumbnailTabHelper::ProcessCapturedBitmap,
+                                   weak_factory_.GetWeakPtr(), algorithm),
+                        kN32_SkColorType);
 }
 
 void ThumbnailTabHelper::ProcessCapturedBitmap(
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index dbfca455..2a8f23b 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1409,7 +1409,6 @@
       "//ash:ash_with_content",
       "//ash/common/strings",
       "//ash/public/cpp:ash_public_cpp",
-      "//ash/public/interfaces",
       "//ash/resources/vector_icons",
       "//components/session_manager/core",
       "//components/user_manager",
diff --git a/chrome/browser/ui/autofill/OWNERS b/chrome/browser/ui/autofill/OWNERS
index f2c30b59..4874525 100644
--- a/chrome/browser/ui/autofill/OWNERS
+++ b/chrome/browser/ui/autofill/OWNERS
@@ -2,3 +2,5 @@
 mathp@chromium.org
 per-file *password*=dvadym@chromium.org
 per-file *password*=vabr@chromium.org
+
+# COMPONENT: UI>Browser>Autofill
diff --git a/chrome/browser/ui/exclusive_access/flash_fullscreen_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/flash_fullscreen_interactive_browsertest.cc
index bdc84aa..15d735d4 100644
--- a/chrome/browser/ui/exclusive_access/flash_fullscreen_interactive_browsertest.cc
+++ b/chrome/browser/ui/exclusive_access/flash_fullscreen_interactive_browsertest.cc
@@ -16,7 +16,6 @@
 #include "chrome/browser/ui/tabs/tab_strip_model.h"
 #include "chrome/test/base/interactive_test_utils.h"
 #include "chrome/test/ppapi/ppapi_test.h"
-#include "content/public/browser/render_widget_host.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/test_utils.h"
@@ -248,23 +247,21 @@
   bool IsObservingFlashFillColor(SkColor expected_color) const {
     content::RenderWidgetHostView* const flash_fs_view =
         GetActiveWebContents()->GetFullscreenRenderWidgetHostView();
-    content::RenderWidgetHost* const flash_fs_host =
-        flash_fs_view ? flash_fs_view->GetRenderWidgetHost() : nullptr;
-    if (!flash_fs_host) {
-      ADD_FAILURE() << "Flash fullscreen RenderWidgetHost is gone.";
+    if (!flash_fs_view) {
+      ADD_FAILURE() << "Flash fullscreen RenderWidgetHostView is gone.";
       return false;
     }
 
     // When a widget is first shown, it can take some time before it is ready
     // for copying from its backing store.  This is a transient condition, and
     // so it is not being treated as a test failure.
-    if (!flash_fs_host->CanCopyFromBackingStore())
+    if (!flash_fs_view->IsSurfaceAvailableForCopy())
       return false;
 
     // Copy and examine the upper-left pixel of the widget and compare it to the
     // |expected_color|.
     bool is_expected_color = false;
-    flash_fs_host->CopyFromBackingStore(
+    flash_fs_view->CopyFromSurface(
         gfx::Rect(0, 0, 1, 1), gfx::Size(1, 1),
         base::Bind(
             &FlashFullscreenInteractiveBrowserTest::CheckBitmapForFillColor,
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
index 392df78..32379884 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller.cc
@@ -184,14 +184,20 @@
   columns->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER,
                      1, views::GridLayout::USE_PREF, 0, 0);
 
+  // The shipping address and contact info rows are optional.
   layout->StartRow(0, 0);
   layout->AddView(CreatePaymentSheetSummaryRow().release());
-  layout->StartRow(1, 0);
-  layout->AddView(CreateShippingRow().release());
+  if (request()->request_shipping()) {
+    layout->StartRow(1, 0);
+    layout->AddView(CreateShippingRow().release());
+  }
   layout->StartRow(0, 0);
   layout->AddView(CreatePaymentMethodRow().release());
-  layout->StartRow(1, 0);
-  layout->AddView(CreateContactInfoRow().release());
+  if (request()->request_payer_name() || request()->request_payer_email() ||
+      request()->request_payer_phone()) {
+    layout->StartRow(1, 0);
+    layout->AddView(CreateContactInfoRow().release());
+  }
 
   return CreatePaymentView(
       CreateSheetHeaderView(
diff --git a/chrome/browser/ui/views/payments/payment_sheet_view_controller_interactive_uitest.cc b/chrome/browser/ui/views/payments/payment_sheet_view_controller_interactive_uitest.cc
index 1c275a9f..67f9276 100644
--- a/chrome/browser/ui/views/payments/payment_sheet_view_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/payments/payment_sheet_view_controller_interactive_uitest.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "base/strings/utf_string_conversions.h"
+#include "chrome/browser/ui/views/payments/payment_request_dialog_view_ids.h"
 #include "chrome/browser/ui/views/payments/payment_request_interactive_uitest_base.h"
 #include "components/autofill/core/browser/autofill_profile.h"
 #include "components/autofill/core/browser/autofill_test_utils.h"
@@ -51,6 +52,22 @@
   EXPECT_FALSE(IsPayButtonEnabled());
 }
 
+// If shipping and contact info are not requested, their rows should not be
+// present.
+IN_PROC_BROWSER_TEST_F(PaymentSheetViewControllerNoShippingTest,
+                       NoShippingNoContactRows) {
+  InvokePaymentRequestUI();
+
+  EXPECT_NE(nullptr, dialog_view()->GetViewByID(static_cast<int>(
+                         DialogViewID::PAYMENT_SHEET_SUMMARY_SECTION)));
+  EXPECT_NE(nullptr, dialog_view()->GetViewByID(static_cast<int>(
+                         DialogViewID::PAYMENT_SHEET_PAYMENT_METHOD_SECTION)));
+  EXPECT_EQ(nullptr, dialog_view()->GetViewByID(static_cast<int>(
+                         DialogViewID::PAYMENT_SHEET_SHIPPING_SECTION)));
+  EXPECT_EQ(nullptr, dialog_view()->GetViewByID(static_cast<int>(
+                         DialogViewID::PAYMENT_SHEET_CONTACT_INFO_SECTION)));
+}
+
 // Accepts 'visa' cards and requests the full contact details.
 class PaymentSheetViewControllerContactDetailsTest
     : public PaymentRequestInteractiveTestBase {
@@ -119,4 +136,19 @@
   EXPECT_FALSE(IsPayButtonEnabled());
 }
 
+// If shipping and contact info are requested, show all the rows.
+IN_PROC_BROWSER_TEST_F(PaymentSheetViewControllerContactDetailsTest,
+                       AllRowsPresent) {
+  InvokePaymentRequestUI();
+
+  EXPECT_NE(nullptr, dialog_view()->GetViewByID(static_cast<int>(
+                         DialogViewID::PAYMENT_SHEET_SUMMARY_SECTION)));
+  EXPECT_NE(nullptr, dialog_view()->GetViewByID(static_cast<int>(
+                         DialogViewID::PAYMENT_SHEET_PAYMENT_METHOD_SECTION)));
+  EXPECT_NE(nullptr, dialog_view()->GetViewByID(static_cast<int>(
+                         DialogViewID::PAYMENT_SHEET_SHIPPING_SECTION)));
+  EXPECT_NE(nullptr, dialog_view()->GetViewByID(static_cast<int>(
+                         DialogViewID::PAYMENT_SHEET_CONTACT_INFO_SECTION)));
+}
+
 }  // namespace payments
diff --git a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.cc
index db8cd34..56759473 100644
--- a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.cc
@@ -19,8 +19,15 @@
 const char kMethodContextChanged[] = "contextChanged";
 }  // namespace
 
+JSCallsContainer::JSCallsContainer() = default;
+
+JSCallsContainer::~JSCallsContainer() = default;
+
 BaseScreenHandler::BaseScreenHandler() = default;
 
+BaseScreenHandler::BaseScreenHandler(JSCallsContainer* js_calls_container)
+    : js_calls_container_(js_calls_container) {}
+
 BaseScreenHandler::~BaseScreenHandler() {
   if (base_screen_)
     base_screen_->set_model_view_channel(nullptr);
@@ -121,4 +128,12 @@
     base_screen_->OnContextChanged(*diff);
 }
 
+void BaseScreenHandler::ExecuteDeferredJSCalls() {
+  DCHECK(!js_calls_container_->is_initialized());
+  js_calls_container_->mark_initialized();
+  for (const auto& deferred_js_call : js_calls_container_->deferred_js_calls())
+    deferred_js_call.Run();
+  js_calls_container_->deferred_js_calls().clear();
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h
index 2e46198..1fae31a 100644
--- a/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/base_screen_handler.h
@@ -32,11 +32,40 @@
 class BaseScreen;
 class OobeUI;
 
+// A helper class to store deferred Javascript calls, shared by subclasses of
+// BaseScreenHandler.
+class JSCallsContainer {
+ public:
+  JSCallsContainer();
+  ~JSCallsContainer();
+
+  // Used to decide whether the JS call should be deferred.
+  bool is_initialized() { return is_initialized_; }
+
+  // Used to mark the instance as intialized.
+  void mark_initialized() { is_initialized_ = true; }
+
+  // Used to add deferred calls to.
+  std::vector<base::Closure>& deferred_js_calls() { return deferred_js_calls_; }
+
+ private:
+  // Whether the instance is initialized.
+  //
+  // The instance becomes initialized after the corresponding message is
+  // received from Javascript side.
+  bool is_initialized_ = false;
+
+  // Javascript calls that have been deferred while the instance was not
+  // initialized yet.
+  std::vector<base::Closure> deferred_js_calls_;
+};
+
 // Base class for the OOBE/Login WebUI handlers.
 class BaseScreenHandler : public content::WebUIMessageHandler,
                           public ModelViewChannel {
  public:
   BaseScreenHandler();
+  explicit BaseScreenHandler(JSCallsContainer* js_calls_container);
   ~BaseScreenHandler() override;
 
   // Gets localized strings to be used on the page.
@@ -122,6 +151,29 @@
         ::login::MakeValue(arg4));
   }
 
+  template <typename... Args>
+  void CallJSOrDefer(const std::string& function_name, const Args&... args) {
+    DCHECK(js_calls_container_);
+    if (js_calls_container_->is_initialized()) {
+      CallJS(function_name, args...);
+    } else {
+      // Note that std::conditional is used here in order to obtain a sequence
+      // of base::Value types with the length equal to sizeof...(Args); the C++
+      // template parameter pack expansion rules require that the name of the
+      // parameter pack appears in the pattern, even though the elements of the
+      // Args pack are not actually in this code.
+      js_calls_container_->deferred_js_calls().push_back(base::Bind(
+          &BaseScreenHandler::ExecuteDeferredJSCall<
+              typename std::conditional<true, base::Value, Args>::type...>,
+          base::Unretained(this), function_name,
+          base::Passed(::login::MakeValue(args).CreateDeepCopy())...));
+    }
+  }
+
+  // Executes Javascript calls that were deferred while the instance was not
+  // initialized yet.
+  void ExecuteDeferredJSCalls();
+
   // Shortcut methods for adding WebUI callbacks.
   template<typename T>
   void AddRawCallback(const std::string& name,
@@ -169,6 +221,16 @@
   void SetBaseScreen(BaseScreen* base_screen);
 
  private:
+  // Calls Javascript method.
+  //
+  // Note that the Args template parameter pack should consist of types
+  // convertible to base::Value.
+  template <typename... Args>
+  void ExecuteDeferredJSCall(const std::string& function_name,
+                             std::unique_ptr<Args>... args) {
+    CallJS(function_name, *args...);
+  }
+
   // Returns full name of JS method based on screen and method
   // names.
   std::string FullMethodPath(const std::string& method) const;
@@ -197,6 +259,8 @@
   // Pending changes to context which will be sent when the page will be ready.
   base::DictionaryValue pending_context_changes_;
 
+  JSCallsContainer* js_calls_container_ = nullptr;  // non-owning pointers.
+
   DISALLOW_COPY_AND_ASSIGN(BaseScreenHandler);
 };
 
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
index 5c4ec9c..15d635e1 100644
--- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.cc
@@ -55,8 +55,12 @@
 
 // Note that show_oobe_ui_ defaults to false because WizardController assumes
 // OOBE UI is not visible by default.
-CoreOobeHandler::CoreOobeHandler(OobeUI* oobe_ui)
-    : oobe_ui_(oobe_ui), version_info_updater_(this) {
+CoreOobeHandler::CoreOobeHandler(OobeUI* oobe_ui,
+                                 JSCallsContainer* js_calls_container)
+    : BaseScreenHandler(js_calls_container),
+      oobe_ui_(oobe_ui),
+      version_info_updater_(this) {
+  DCHECK(js_calls_container);
   set_call_js_prefix(kJsScreenPath);
   if (!ash_util::IsRunningInMash()) {
     AccessibilityManager* accessibility_manager = AccessibilityManager::Get();
@@ -164,37 +168,6 @@
               &CoreOobeHandler::HandleSetOobeBootstrappingSlave);
 }
 
-template <typename... Args>
-void CoreOobeHandler::ExecuteDeferredJSCall(const std::string& function_name,
-                                            std::unique_ptr<Args>... args) {
-  CallJS(function_name, *args...);
-}
-
-template <typename... Args>
-void CoreOobeHandler::CallJSOrDefer(const std::string& function_name,
-                                    const Args&... args) {
-  if (is_initialized_) {
-    CallJS(function_name, args...);
-  } else {
-    // Note that std::conditional is used here in order to obtain a sequence of
-    // base::Value types with the length equal to sizeof...(Args); the C++
-    // template parameter pack expansion rules require that the name of the
-    // parameter pack appears in the pattern, even though the elements of the
-    // Args pack are not actually in this code.
-    deferred_js_calls_.push_back(base::Bind(
-        &CoreOobeHandler::ExecuteDeferredJSCall<
-            typename std::conditional<true, base::Value, Args>::type...>,
-        base::Unretained(this), function_name,
-        base::Passed(::login::MakeValue(args).CreateDeepCopy())...));
-  }
-}
-
-void CoreOobeHandler::ExecuteDeferredJSCalls() {
-  for (const auto& deferred_js_call : deferred_js_calls_)
-    deferred_js_call.Run();
-  deferred_js_calls_.clear();
-}
-
 void CoreOobeHandler::ShowSignInError(
     int login_attempts,
     const std::string& error_text,
@@ -295,8 +268,6 @@
 }
 
 void CoreOobeHandler::HandleInitialized() {
-  DCHECK(!is_initialized_);
-  is_initialized_ = true;
   ExecuteDeferredJSCalls();
   oobe_ui_->InitializeHandlers();
 }
diff --git a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h
index 9ec98915..33a11e9 100644
--- a/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/core_oobe_handler.h
@@ -45,7 +45,8 @@
     virtual void OnCurrentScreenChanged(OobeScreen screen) = 0;
   };
 
-  explicit CoreOobeHandler(OobeUI* oobe_ui);
+  explicit CoreOobeHandler(OobeUI* oobe_ui,
+                           JSCallsContainer* js_calls_container);
   ~CoreOobeHandler() override;
 
   void SetDelegate(Delegate* delegate);
@@ -80,23 +81,6 @@
   void UpdateShutdownAndRebootVisibility(bool reboot_on_shutdown);
 
  private:
-  // Calls javascript method.
-  //
-  // Note that the Args template parameter pack should consist of types
-  // convertible to base::Value.
-  template <typename... Args>
-  void ExecuteDeferredJSCall(const std::string& function_name,
-                             std::unique_ptr<Args>... args);
-
-  // Calls javascript method if the instance is already initialized, or defers
-  // the call until it gets initialized.
-  template <typename... Args>
-  void CallJSOrDefer(const std::string& function_name, const Args&... args);
-
-  // Executes javascript calls that were deferred while the instance was not
-  // initialized yet.
-  void ExecuteDeferredJSCalls();
-
   // CoreOobeActor implementation:
   void ShowSignInError(int login_attempts,
                        const std::string& error_text,
@@ -168,16 +152,6 @@
   void OnAccessibilityStatusChanged(
       const AccessibilityStatusEventDetails& details);
 
-  // Whether the instance is initialized.
-  //
-  // The instance becomes initialized after the corresponding message is
-  // received from javascript side.
-  bool is_initialized_ = false;
-
-  // Javascript calls that have been deferred while the instance was not
-  // initialized yet.
-  std::vector<base::Closure> deferred_js_calls_;
-
   // Owner of this handler.
   OobeUI* oobe_ui_ = nullptr;
 
diff --git a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
index 14819d7..00427f8 100644
--- a/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/network_screen_handler.cc
@@ -154,6 +154,7 @@
   builder->Add("selectKeyboard", IDS_KEYBOARD_SELECTION_SELECT);
   builder->Add("selectNetwork", IDS_NETWORK_SELECTION_SELECT);
   builder->Add("selectTimezone", IDS_OPTIONS_SETTINGS_TIMEZONE_DESCRIPTION);
+  builder->Add("timezoneDropdownLabel", IDS_TIMEZONE_DROPDOWN_LABEL);
   builder->Add("proxySettings", IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON);
   builder->Add("continueButton", IDS_NETWORK_SELECTION_CONTINUE_BUTTON);
   builder->Add("debuggingFeaturesLink", IDS_NETWORK_ENABLE_DEV_FEATURES_LINK);
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
index 5929440..281702d 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.cc
@@ -213,7 +213,10 @@
   network_state_informer_ = new NetworkStateInformer();
   network_state_informer_->Init();
 
-  auto core_handler = base::MakeUnique<CoreOobeHandler>(this);
+  js_calls_container = base::MakeUnique<JSCallsContainer>();
+
+  auto core_handler =
+      base::MakeUnique<CoreOobeHandler>(this, js_calls_container.get());
   core_handler_ = core_handler.get();
   AddScreenHandler(std::move(core_handler));
   core_handler_->SetDelegate(this);
@@ -315,7 +318,7 @@
 
   auto signin_screen_handler = base::MakeUnique<SigninScreenHandler>(
       network_state_informer_, error_screen, core_handler_,
-      gaia_screen_handler_);
+      gaia_screen_handler_, js_calls_container.get());
   signin_screen_handler_ = signin_screen_handler.get();
   AddScreenHandler(std::move(signin_screen_handler));
 
diff --git a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
index e7c75be..73748fe 100644
--- a/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
+++ b/chrome/browser/ui/webui/chromeos/login/oobe_ui.h
@@ -260,6 +260,10 @@
 
   std::unique_ptr<ash::ScreenDimmer> screen_dimmer_;
 
+  // Store the deferred JS calls before the screen handler instance is
+  // initialized.
+  std::unique_ptr<JSCallsContainer> js_calls_container;
+
   DISALLOW_COPY_AND_ASSIGN(OobeUI);
 };
 
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
index 8471f1f..3e90662 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.cc
@@ -291,8 +291,10 @@
     const scoped_refptr<NetworkStateInformer>& network_state_informer,
     ErrorScreen* error_screen,
     CoreOobeView* core_oobe_view,
-    GaiaScreenHandler* gaia_screen_handler)
-    : network_state_informer_(network_state_informer),
+    GaiaScreenHandler* gaia_screen_handler,
+    JSCallsContainer* js_calls_container)
+    : BaseScreenHandler(js_calls_container),
+      network_state_informer_(network_state_informer),
       error_screen_(error_screen),
       core_oobe_view_(core_oobe_view),
       caps_lock_enabled_(chromeos::input_method::InputMethodManager::Get()
@@ -306,6 +308,7 @@
   DCHECK(network_state_informer_.get());
   DCHECK(error_screen_);
   DCHECK(core_oobe_view_);
+  DCHECK(js_calls_container);
   gaia_screen_handler_->set_signin_screen_handler(this);
   network_state_informer_->AddObserver(this);
 
@@ -1136,7 +1139,7 @@
 
 void SigninScreenHandler::OnTouchViewToggled(bool enabled) {
   touch_view_enabled_ = enabled;
-  CallJS("login.AccountPickerScreen.setTouchViewState", enabled);
+  CallJSOrDefer("login.AccountPickerScreen.setTouchViewState", enabled);
 }
 
 bool SigninScreenHandler::ShouldLoadGaia() const {
diff --git a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
index b174e1d..57d1043d 100644
--- a/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
+++ b/chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h
@@ -231,7 +231,8 @@
       const scoped_refptr<NetworkStateInformer>& network_state_informer,
       ErrorScreen* error_screen,
       CoreOobeView* core_oobe_view,
-      GaiaScreenHandler* gaia_screen_handler);
+      GaiaScreenHandler* gaia_screen_handler,
+      JSCallsContainer* js_calls_container);
   ~SigninScreenHandler() override;
 
   static std::string GetUserLRUInputMethod(const std::string& username);
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 864e00f..6777728 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
@@ -962,6 +962,7 @@
     {"manageInputMethods", IDS_SETTINGS_LANGUAGES_INPUT_METHODS_MANAGE},
     {"manageInputMethodsPageTitle",
      IDS_SETTINGS_LANGUAGES_MANAGE_INPUT_METHODS_TITLE},
+    {"showImeMenu", IDS_SETTINGS_LANGUAGES_SHOW_IME_MENU},
 #endif
     {"addLanguagesDialogTitle", IDS_SETTINGS_LANGUAGES_MANAGE_LANGUAGES_TITLE},
     {"allLanguages", IDS_SETTINGS_LANGUAGES_ALL_LANGUAGES},
diff --git a/chrome/common/BUILD.gn b/chrome/common/BUILD.gn
index 8c506e1d..856a1d4 100644
--- a/chrome/common/BUILD.gn
+++ b/chrome/common/BUILD.gn
@@ -581,6 +581,7 @@
     "//content/public/common:result_codes",
     "//extensions/features",
     "//printing/features",
+    "//rlz/features",
   ]
   deps = [
     ":version_header",
diff --git a/chrome/common/DEPS b/chrome/common/DEPS
index 10fabe5..e6b1509 100644
--- a/chrome/common/DEPS
+++ b/chrome/common/DEPS
@@ -35,6 +35,7 @@
   "+ppapi/c",
   "+ppapi/shared_impl",
   "+ppapi/thunk",
+  "+rlz/features/features.h",
   "+sandbox/linux/services/credentials.h",
   "+third_party/boringssl/src/include",
 
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index 254cdb9..007f6de 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -186,6 +186,11 @@
 // (currently the name).
 const char kSupervisedUserWhitelists[] = "profile.managed.whitelists";
 
+#if BUILDFLAG(ENABLE_RLZ)
+// Integer. RLZ ping delay in seconds.
+const char kRlzPingDelaySeconds[] = "rlz_ping_delay";
+#endif  // BUILDFLAG(ENABLE_RLZ)
+
 // The application locale.
 // For OS_CHROMEOS we maintain the kApplicationLocale property in both local
 // state and the user's profile.  The global property determines the locale of
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 03a07aa..9082a8d 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -14,6 +14,7 @@
 #include "extensions/features/features.h"
 #include "media/media_features.h"
 #include "ppapi/features/features.h"
+#include "rlz/features/features.h"
 
 namespace prefs {
 
@@ -61,6 +62,10 @@
 extern const char kSupervisedUserWhitelists[];
 extern const char kURLsToRestoreOnStartup[];
 
+#if BUILDFLAG(ENABLE_RLZ)
+extern const char kRlzPingDelaySeconds[];
+#endif  // BUILDFLAG(ENABLE_RLZ)
+
 // For OS_CHROMEOS we maintain the kApplicationLocale property in both local
 // state and the user's profile.  The global property determines the locale of
 // the login screen, while the user's profile determines their personal locale
diff --git a/chrome/installer/util/BUILD.gn b/chrome/installer/util/BUILD.gn
index 005ea05..c8012ca 100644
--- a/chrome/installer/util/BUILD.gn
+++ b/chrome/installer/util/BUILD.gn
@@ -100,6 +100,7 @@
       "//components/metrics",
       "//courgette:courgette_lib",
       "//crypto",
+      "//rlz/features",
       "//third_party/bspatch",
       "//third_party/crashpad/crashpad/client",
       "//third_party/icu",
@@ -334,6 +335,7 @@
       "//chrome/installer/setup:lib",
       "//chrome/installer/test:alternate_version_generator_lib",
       "//components/variations",
+      "//rlz/features",
       "//testing/gmock",
       "//testing/gtest",
     ]
diff --git a/chrome/installer/util/master_preferences.cc b/chrome/installer/util/master_preferences.cc
index 2f7ccb6..c48a4f4 100644
--- a/chrome/installer/util/master_preferences.cc
+++ b/chrome/installer/util/master_preferences.cc
@@ -19,6 +19,7 @@
 #include "chrome/installer/util/master_preferences_constants.h"
 #include "chrome/installer/util/util_constants.h"
 #include "components/variations/pref_names.h"
+#include "rlz/features/features.h"
 
 namespace {
 
@@ -207,17 +208,32 @@
 }
 
 void MasterPreferences::EnforceLegacyPreferences() {
+  // Boolean. This is a legacy preference and should no longer be used; it is
+  // kept around so that old master_preferences which specify
+  // "create_all_shortcuts":false still enforce the new
+  // "do_not_create_(desktop|quick_launch)_shortcut" preferences. Setting this
+  // to true no longer has any impact.
+  static constexpr char kCreateAllShortcuts[] = "create_all_shortcuts";
+
   // If create_all_shortcuts was explicitly set to false, set
   // do_not_create_(desktop|quick_launch)_shortcut to true.
   bool create_all_shortcuts = true;
-  GetBool(installer::master_preferences::kCreateAllShortcuts,
-          &create_all_shortcuts);
+  GetBool(kCreateAllShortcuts, &create_all_shortcuts);
   if (!create_all_shortcuts) {
     distribution_->SetBoolean(
         installer::master_preferences::kDoNotCreateDesktopShortcut, true);
     distribution_->SetBoolean(
         installer::master_preferences::kDoNotCreateQuickLaunchShortcut, true);
   }
+
+#if BUILDFLAG(ENABLE_RLZ)
+  // Map the RLZ ping delay shipped in the distribution dictionary into real
+  // prefs.
+  static constexpr char kDistroPingDelay[] = "ping_delay";
+  int rlz_ping_delay = 0;
+  if (GetInt(kDistroPingDelay, &rlz_ping_delay))
+    master_dictionary_->SetInteger(prefs::kRlzPingDelaySeconds, rlz_ping_delay);
+#endif  // BUILDFLAG(ENABLE_RLZ)
 }
 
 bool MasterPreferences::GetBool(const std::string& name, bool* value) const {
diff --git a/chrome/installer/util/master_preferences.h b/chrome/installer/util/master_preferences.h
index 4c570486..61582943 100644
--- a/chrome/installer/util/master_preferences.h
+++ b/chrome/installer/util/master_preferences.h
@@ -38,18 +38,18 @@
 // {
 //   "distribution": {
 //      "create_all_shortcuts": true,
+//      "do_not_launch_chrome": false,
 //      "import_bookmarks": false,
 //      "import_bookmarks_from_file": "c:\\path",
 //      "import_history": false,
 //      "import_home_page": false,
 //      "import_search_engine": true,
-//      "ping_delay": 40,
-//      "show_welcome_page": true,
-//      "skip_first_run_ui": true,
-//      "do_not_launch_chrome": false,
 //      "make_chrome_default": false,
 //      "make_chrome_default_for_user": true,
+//      "ping_delay": 40,
 //      "require_eula": true,
+//      "show_welcome_page": true,
+//      "skip_first_run_ui": true,
 //      "system_level": false,
 //      "verbose_logging": true,
 //      "welcome_page_on_os_upgrade_enabled": false
diff --git a/chrome/installer/util/master_preferences_constants.cc b/chrome/installer/util/master_preferences_constants.cc
index 0af4ab9..2a1aeed 100644
--- a/chrome/installer/util/master_preferences_constants.cc
+++ b/chrome/installer/util/master_preferences_constants.cc
@@ -6,7 +6,6 @@
 
 namespace installer {
 namespace master_preferences {
-  const char kCreateAllShortcuts[] = "create_all_shortcuts";
   const char kDisableLogging[] = "disable_logging";
   const char kDistroDict[] = "distribution";
   const char kDistroImportBookmarksPref[] = "import_bookmarks";
@@ -15,7 +14,6 @@
   const char kDistroImportHistoryPref[] = "import_history";
   const char kDistroImportHomePagePref[] = "import_home_page";
   const char kDistroImportSearchPref[] = "import_search_engine";
-  const char kDistroPingDelay[] = "ping_delay";
   const char kDistroSuppressDefaultBrowserPromptPref[] =
       "suppress_default_browser_prompt_for_version";
   const char kDistroSuppressFirstRunBubble[] = "suppress_first_run_bubble";
diff --git a/chrome/installer/util/master_preferences_constants.h b/chrome/installer/util/master_preferences_constants.h
index 92bbe4b..c37b732 100644
--- a/chrome/installer/util/master_preferences_constants.h
+++ b/chrome/installer/util/master_preferences_constants.h
@@ -15,12 +15,6 @@
 // is specified in master preference as well as command line, the command line
 // value takes precedence.
 
-// Boolean. This is a legacy preference and should no longer be used; it is
-// kept around so that old master_preferences which specify
-// "create_all_shortcuts":false still enforce the new
-// "do_not_create_(desktop|quick_launch)_shortcut" preferences. Setting this to
-// true no longer has any impact.
-extern const char kCreateAllShortcuts[];
 // Boolean pref that disables all logging.
 extern const char kDisableLogging[];
 // Name of the dictionary that holds the distribution values.
@@ -36,8 +30,6 @@
 extern const char kDistroImportHomePagePref[];
 // Boolean pref that triggers silent import of the default search engine.
 extern const char kDistroImportSearchPref[];
-// Integer. RLZ ping delay in seconds.
-extern const char kDistroPingDelay[];
 // String of Chrome version for which the "set as default browser" infobar will
 // never be shown.
 extern const char kDistroSuppressDefaultBrowserPromptPref[];
diff --git a/chrome/installer/util/master_preferences_unittest.cc b/chrome/installer/util/master_preferences_unittest.cc
index 019ac57..e91b8b9 100644
--- a/chrome/installer/util/master_preferences_unittest.cc
+++ b/chrome/installer/util/master_preferences_unittest.cc
@@ -19,6 +19,7 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/installer/util/master_preferences_constants.h"
 #include "chrome/installer/util/util_constants.h"
+#include "rlz/features/features.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace {
@@ -89,8 +90,7 @@
       "     \"make_chrome_default_for_user\": true,\n"
       "     \"system_level\": true,\n"
       "     \"verbose_logging\": true,\n"
-      "     \"require_eula\": true,\n"
-      "     \"ping_delay\": 40\n"
+      "     \"require_eula\": true\n"
       "  },\n"
       "  \"blah\": {\n"
       "     \"import_history\": false\n"
@@ -131,11 +131,6 @@
       installer::master_preferences::kDistroImportBookmarksFromFilePref,
       &str_value));
   EXPECT_STREQ("c:\\foo", str_value.c_str());
-
-  int ping_delay = 90;
-  EXPECT_TRUE(prefs.GetInt(installer::master_preferences::kDistroPingDelay,
-                           &ping_delay));
-  EXPECT_EQ(ping_delay, 40);
 }
 
 TEST_F(MasterPreferencesTest, ParseMissingDistroParams) {
@@ -186,11 +181,6 @@
   EXPECT_FALSE(prefs.GetString(
       installer::master_preferences::kDistroImportBookmarksFromFilePref,
       &str_value));
-
-  int ping_delay = 90;
-  EXPECT_FALSE(prefs.GetInt(
-      installer::master_preferences::kDistroPingDelay, &ping_delay));
-  EXPECT_EQ(ping_delay, 90);
 }
 
 TEST_F(MasterPreferencesTest, FirstRunTabs) {
@@ -323,34 +313,39 @@
   installer::MasterPreferences pref_chrome(chrome_install);
 }
 
-TEST_F(MasterPreferencesTest, EnforceLegacyCreateAllShortcutsFalse) {
-  static const char kCreateAllShortcutsFalsePrefs[] =
+TEST_F(MasterPreferencesTest, EnforceLegacyPreferences) {
+  static const char kLegacyPrefs[] =
       "{"
       "  \"distribution\": {"
-      "     \"create_all_shortcuts\": false"
+      "     \"create_all_shortcuts\": false,\n"
+      "     \"ping_delay\": 40\n"
       "  }"
       "}";
 
-    installer::MasterPreferences prefs(kCreateAllShortcutsFalsePrefs);
+  installer::MasterPreferences prefs(kLegacyPrefs);
 
-    bool do_not_create_desktop_shortcut = false;
-    bool do_not_create_quick_launch_shortcut = false;
-    bool do_not_create_taskbar_shortcut = false;
-    prefs.GetBool(
-        installer::master_preferences::kDoNotCreateDesktopShortcut,
-        &do_not_create_desktop_shortcut);
-    prefs.GetBool(
-        installer::master_preferences::kDoNotCreateQuickLaunchShortcut,
-        &do_not_create_quick_launch_shortcut);
-    prefs.GetBool(
-        installer::master_preferences::kDoNotCreateTaskbarShortcut,
-        &do_not_create_taskbar_shortcut);
-    // create_all_shortcuts is a legacy preference that should only enforce
-    // do_not_create_desktop_shortcut and do_not_create_quick_launch_shortcut
-    // when set to false.
-    EXPECT_TRUE(do_not_create_desktop_shortcut);
-    EXPECT_TRUE(do_not_create_quick_launch_shortcut);
-    EXPECT_FALSE(do_not_create_taskbar_shortcut);
+  bool do_not_create_desktop_shortcut = false;
+  bool do_not_create_quick_launch_shortcut = false;
+  bool do_not_create_taskbar_shortcut = false;
+  prefs.GetBool(installer::master_preferences::kDoNotCreateDesktopShortcut,
+                &do_not_create_desktop_shortcut);
+  prefs.GetBool(installer::master_preferences::kDoNotCreateQuickLaunchShortcut,
+                &do_not_create_quick_launch_shortcut);
+  prefs.GetBool(installer::master_preferences::kDoNotCreateTaskbarShortcut,
+                &do_not_create_taskbar_shortcut);
+  // create_all_shortcuts is a legacy preference that should only enforce
+  // do_not_create_desktop_shortcut and do_not_create_quick_launch_shortcut
+  // when set to false.
+  EXPECT_TRUE(do_not_create_desktop_shortcut);
+  EXPECT_TRUE(do_not_create_quick_launch_shortcut);
+  EXPECT_FALSE(do_not_create_taskbar_shortcut);
+
+#if BUILDFLAG(ENABLE_RLZ)
+  int rlz_ping_delay = 0;
+  EXPECT_TRUE(prefs.master_dictionary().GetInteger(prefs::kRlzPingDelaySeconds,
+                                                   &rlz_ping_delay));
+  EXPECT_EQ(40, rlz_ping_delay);
+#endif  // BUILDFLAG(ENABLE_RLZ)
 }
 
 TEST_F(MasterPreferencesTest, DontEnforceLegacyCreateAllShortcutsTrue) {
diff --git a/chrome/renderer/autofill/OWNERS b/chrome/renderer/autofill/OWNERS
index 9d66397..e1ff0df 100644
--- a/chrome/renderer/autofill/OWNERS
+++ b/chrome/renderer/autofill/OWNERS
@@ -5,3 +5,5 @@
 vabr@chromium.org
 
 per-file password*=gcasto@chromium.org
+
+# COMPONENT: UI>Browser>Autofill
diff --git a/chrome/renderer/media/OWNERS b/chrome/renderer/media/OWNERS
index 60c23922..d8b5cac7 100644
--- a/chrome/renderer/media/OWNERS
+++ b/chrome/renderer/media/OWNERS
@@ -5,3 +5,5 @@
 # For Cast streaming changes.
 per-file cast_*=hubbe@chromium.org
 per-file cast_*=miu@chromium.org
+
+# COMPONENT: Internals>Media
diff --git a/chrome/test/data/webui/cr_elements/cr_dialog_test.js b/chrome/test/data/webui/cr_elements/cr_dialog_test.js
index fa617c5..5f9c1b1 100644
--- a/chrome/test/data/webui/cr_elements/cr_dialog_test.js
+++ b/chrome/test/data/webui/cr_elements/cr_dialog_test.js
@@ -14,13 +14,16 @@
         <div class="body"><button>button</button></div>
       </dialog>`;
 
-    assertFalse(document.activeElement.matches('div.title'));
-    assertFalse(document.activeElement.matches('button'));
+    var dialog = document.body.querySelector('dialog');
+    var button = document.body.querySelector('button');
 
-    document.body.querySelector('dialog').showModal();
+    assertNotEquals(dialog, document.activeElement);
+    assertNotEquals(button, document.activeElement);
 
-    expectTrue(document.activeElement.matches('div.title'));
-    expectFalse(document.activeElement.matches('button'));
+    dialog.showModal();
+
+    expectEquals(dialog, document.activeElement);
+    expectNotEquals(button, document.activeElement);
   });
 
   test('focuses [autofocus] instead of title when present', function() {
@@ -30,12 +33,15 @@
         <div class="body"><button autofocus>button</button></div>
       </dialog>`;
 
-    assertFalse(document.activeElement.matches('button'));
-    assertFalse(document.activeElement.matches('div.title'));
+    var dialog = document.body.querySelector('dialog');
+    var button = document.body.querySelector('button');
 
-    document.body.querySelector('dialog').showModal();
+    assertNotEquals(dialog, document.activeElement);
+    assertNotEquals(button, document.activeElement);
 
-    expectTrue(document.activeElement.matches('button'));
-    expectFalse(document.activeElement.matches('div.title'));
+    dialog.showModal();
+
+    expectNotEquals(dialog, document.activeElement);
+    expectEquals(button, document.activeElement);
   });
 });
diff --git a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
index 20cb50e9..8485a0d 100644
--- a/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
+++ b/chrome/test/data/webui/cr_elements/cr_elements_browsertest.js
@@ -183,6 +183,30 @@
  * @constructor
  * @extends {CrElementsBrowserTest}
  */
+function CrElementsPolicyIndicatorBehaviorTest() {}
+
+CrElementsPolicyIndicatorBehaviorTest.prototype = {
+  __proto__: CrElementsBrowserTest.prototype,
+
+  /** @override */
+  browsePreload:
+      'chrome://resources/cr_elements/policy/cr_policy_indicator_behavior.html',
+
+  /** @override */
+  extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([
+    'cr_policy_strings.js',
+    'cr_policy_indicator_behavior_tests.js',
+  ]),
+};
+
+TEST_F('CrElementsPolicyIndicatorBehaviorTest', 'All', function() {
+  mocha.run();
+});
+
+/**
+ * @constructor
+ * @extends {CrElementsBrowserTest}
+ */
 function CrElementsPolicyPrefIndicatorTest() {}
 
 CrElementsPolicyPrefIndicatorTest.prototype = {
@@ -194,6 +218,7 @@
 
   /** @override */
   extraLibraries: CrElementsBrowserTest.prototype.extraLibraries.concat([
+    'cr_policy_strings.js',
     'cr_policy_pref_indicator_tests.js',
   ]),
 };
diff --git a/chrome/test/data/webui/cr_elements/cr_policy_indicator_behavior_tests.js b/chrome/test/data/webui/cr_elements/cr_policy_indicator_behavior_tests.js
new file mode 100644
index 0000000..049c9b1b
--- /dev/null
+++ b/chrome/test/data/webui/cr_elements/cr_policy_indicator_behavior_tests.js
@@ -0,0 +1,59 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/** @fileoverview Suite of tests for CrPolicyIndicatorBehavior. */
+suite('CrPolicyIndicatorBehavior', function() {
+  var TestIndicator;
+  suiteSetup(function() {
+    TestIndicator = Polymer({
+      is: 'test-indicator',
+
+      behaviors: [CrPolicyIndicatorBehavior],
+    });
+  });
+
+  var indicator;
+  setup(function() {
+    indicator = new TestIndicator;
+  });
+
+  test('default indicator is blank', function() {
+    assertEquals(CrPolicyIndicatorType.NONE, indicator.indicatorType)
+    assertFalse(indicator.indicatorVisible);
+  });
+
+  test('policy-controlled indicator', function() {
+    indicator.indicatorType = CrPolicyIndicatorType.USER_POLICY;
+
+    assertTrue(indicator.indicatorVisible);
+    assertEquals('cr20:domain', indicator.indicatorIcon);
+    assertEquals('policy', indicator.indicatorTooltip);
+  });
+
+  test('recommended indicator', function() {
+    indicator.indicatorType = CrPolicyIndicatorType.RECOMMENDED;
+
+    assertTrue(indicator.indicatorVisible);
+    assertEquals('cr20:domain', indicator.indicatorIcon);
+    assertEquals(
+        'matches',
+        indicator.getIndicatorTooltip(
+            indicator.indicatorType, indicator.indicatorSourceName, true));
+    assertEquals(
+        'differs',
+        indicator.getIndicatorTooltip(
+            indicator.indicatorType, indicator.indicatorSourceName, false));
+  });
+
+  if (cr.isChromeOS) {
+    test('primary-user controlled indicator', function() {
+      indicator.indicatorType = CrPolicyIndicatorType.PRIMARY_USER;
+      indicator.indicatorSourceName = 'user@example.com';
+
+      assertTrue(indicator.indicatorVisible);
+      assertEquals('cr:group', indicator.indicatorIcon);
+      assertEquals('shared: user@example.com', indicator.indicatorTooltip);
+    });
+  }
+});
diff --git a/chrome/test/data/webui/cr_elements/cr_policy_pref_indicator_tests.js b/chrome/test/data/webui/cr_elements/cr_policy_pref_indicator_tests.js
index 13169cb..3762b6ad 100644
--- a/chrome/test/data/webui/cr_elements/cr_policy_pref_indicator_tests.js
+++ b/chrome/test/data/webui/cr_elements/cr_policy_pref_indicator_tests.js
@@ -40,15 +40,6 @@
       LIST: 'LIST',
       DICTIONARY: 'DICTIONARY',
     };
-
-    // Set up strings used by policy indicator elements.
-    CrPolicyStrings = {
-      controlledSettingPolicy: 'policy',
-      controlledSettingRecommendedMatches: 'matches',
-      controlledSettingRecommendedDiffers: 'differs',
-      controlledSettingShared: 'shared: $1',
-      controlledSettingOwner: 'owner: $1',
-    };
   });
 
   setup(function() {
diff --git a/chrome/test/data/webui/cr_elements/cr_policy_strings.js b/chrome/test/data/webui/cr_elements/cr_policy_strings.js
new file mode 100644
index 0000000..c9cd1eb
--- /dev/null
+++ b/chrome/test/data/webui/cr_elements/cr_policy_strings.js
@@ -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.
+
+/** @fileoverview Sets up strings used by policy indicator elements. */
+var CrPolicyStrings = CrPolicyStrings || {
+  controlledSettingPolicy: 'policy',
+  controlledSettingRecommendedMatches: 'matches',
+  controlledSettingRecommendedDiffers: 'differs',
+  controlledSettingShared: 'shared: $1',
+  controlledSettingOwner: 'owner: $1',
+};
diff --git a/chrome/test/data/webui/settings/date_time_page_tests.js b/chrome/test/data/webui/settings/date_time_page_tests.js
index b5889bf5..9357a05 100644
--- a/chrome/test/data/webui/settings/date_time_page_tests.js
+++ b/chrome/test/data/webui/settings/date_time_page_tests.js
@@ -121,7 +121,7 @@
 
       if (policy) {
         assertTrue(!!indicator);
-        assertTrue(indicator.isActive());
+        assertTrue(indicator.indicatorVisible);
       } else {
         // Indicator should be missing dom-ifed out.
         assertFalse(!!indicator);
diff --git a/chrome/test/remoting/OWNERS b/chrome/test/remoting/OWNERS
index 222b498..cf68d306 100644
--- a/chrome/test/remoting/OWNERS
+++ b/chrome/test/remoting/OWNERS
@@ -5,3 +5,5 @@
 sergeyu@chromium.org
 alog@chromium.org
 wez@chromium.org
+
+# COMPONENT: Services>Chromoting 
diff --git a/chromeos/components/tether/BUILD.gn b/chromeos/components/tether/BUILD.gn
index b43d203..031b805 100644
--- a/chromeos/components/tether/BUILD.gn
+++ b/chromeos/components/tether/BUILD.gn
@@ -16,6 +16,8 @@
     "ble_constants.h",
     "ble_scanner.cc",
     "ble_scanner.h",
+    "connect_tethering_operation.cc",
+    "connect_tethering_operation.h",
     "host_scan_device_prioritizer.cc",
     "host_scan_device_prioritizer.h",
     "host_scan_scheduler.cc",
@@ -32,6 +34,8 @@
     "message_wrapper.h",
     "pref_names.cc",
     "pref_names.h",
+    "tether_host_fetcher.cc",
+    "tether_host_fetcher.h",
   ]
 
   deps = [
@@ -79,11 +83,13 @@
     "ble_advertiser_unittest.cc",
     "ble_connection_manager_unittest.cc",
     "ble_scanner_unittest.cc",
+    "connect_tethering_operation_unittest.cc",
     "host_scan_device_prioritizer_unittest.cc",
     "host_scan_scheduler_unittest.cc",
     "local_device_data_provider_unittest.cc",
     "message_transfer_operation_unittest.cc",
     "message_wrapper_unittest.cc",
+    "tether_host_fetcher_unittest.cc",
   ]
 
   deps = [
diff --git a/chromeos/components/tether/connect_tethering_operation.cc b/chromeos/components/tether/connect_tethering_operation.cc
new file mode 100644
index 0000000..114c0d42
--- /dev/null
+++ b/chromeos/components/tether/connect_tethering_operation.cc
@@ -0,0 +1,146 @@
+// 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/connect_tethering_operation.h"
+
+#include "chromeos/components/tether/message_wrapper.h"
+#include "chromeos/components/tether/proto/tether.pb.h"
+#include "components/proximity_auth/logging/logging.h"
+
+namespace chromeos {
+
+namespace tether {
+
+// static
+ConnectTetheringOperation::Factory*
+    ConnectTetheringOperation::Factory::factory_instance_ = nullptr;
+
+// static
+std::unique_ptr<ConnectTetheringOperation>
+ConnectTetheringOperation::Factory::NewInstance(
+    const cryptauth::RemoteDevice& device_to_connect,
+    BleConnectionManager* connection_manager) {
+  if (!factory_instance_) {
+    factory_instance_ = new Factory();
+  }
+  return factory_instance_->BuildInstance(device_to_connect,
+                                          connection_manager);
+}
+
+// static
+void ConnectTetheringOperation::Factory::SetInstanceForTesting(
+    Factory* factory) {
+  factory_instance_ = factory;
+}
+
+std::unique_ptr<ConnectTetheringOperation>
+ConnectTetheringOperation::Factory::BuildInstance(
+    const cryptauth::RemoteDevice& device_to_connect,
+    BleConnectionManager* connection_manager) {
+  return base::MakeUnique<ConnectTetheringOperation>(device_to_connect,
+                                                     connection_manager);
+}
+
+ConnectTetheringOperation::ConnectTetheringOperation(
+    const cryptauth::RemoteDevice& device_to_connect,
+    BleConnectionManager* connection_manager)
+    : MessageTransferOperation(
+          std::vector<cryptauth::RemoteDevice>{device_to_connect},
+          connection_manager),
+      has_authenticated_(false) {}
+
+ConnectTetheringOperation::~ConnectTetheringOperation() {}
+
+void ConnectTetheringOperation::AddObserver(Observer* observer) {
+  observer_list_.AddObserver(observer);
+}
+
+void ConnectTetheringOperation::RemoveObserver(Observer* observer) {
+  observer_list_.RemoveObserver(observer);
+}
+
+void ConnectTetheringOperation::OnDeviceAuthenticated(
+    const cryptauth::RemoteDevice& remote_device) {
+  DCHECK(remote_devices().size() == 1u && remote_devices()[0] == remote_device);
+  has_authenticated_ = true;
+
+  SendMessageToDevice(remote_device, base::MakeUnique<MessageWrapper>(
+                                         ConnectTetheringRequest()));
+}
+
+void ConnectTetheringOperation::OnMessageReceived(
+    std::unique_ptr<MessageWrapper> message_wrapper,
+    const cryptauth::RemoteDevice& remote_device) {
+  if (message_wrapper->GetMessageType() !=
+      MessageType::CONNECT_TETHERING_RESPONSE) {
+    // If another type of message has been received, ignore it.
+    return;
+  }
+
+  ConnectTetheringResponse* response =
+      static_cast<ConnectTetheringResponse*>(message_wrapper->GetProto().get());
+  if (response->response_code() ==
+      ConnectTetheringResponse_ResponseCode::
+          ConnectTetheringResponse_ResponseCode_SUCCESS) {
+    if (response->has_ssid() && response->has_password()) {
+      PA_LOG(INFO) << "Received ConnectTetheringResponse from device with ID "
+                   << remote_device.GetTruncatedDeviceIdForLogs() << " and "
+                   << "response_code == SUCCESS. Config: {ssid: \""
+                   << response->ssid() << "\", password: \""
+                   << response->password() << "\"}";
+      NotifyObserversOfSuccessfulResponse(response->ssid(),
+                                          response->password());
+    } else {
+      PA_LOG(ERROR) << "Received ConnectTetheringResponse from device with ID "
+                    << remote_device.GetTruncatedDeviceIdForLogs() << " and "
+                    << "response_code == SUCCESS, but the response did not "
+                    << "contain a Wi-Fi SSID and/or password.";
+      NotifyObserversOfConnectionFailure(
+          ConnectTetheringResponse_ResponseCode::
+              ConnectTetheringResponse_ResponseCode_UNKNOWN_ERROR);
+    }
+  } else {
+    PA_LOG(INFO) << "Received ConnectTetheringResponse from device with ID "
+                 << remote_device.GetTruncatedDeviceIdForLogs() << " and "
+                 << "response_code == " << response->response_code() << ".";
+    NotifyObserversOfConnectionFailure(response->response_code());
+  }
+
+  // Now that a response has been received, the device can be unregistered.
+  UnregisterDevice(remote_device);
+}
+
+void ConnectTetheringOperation::OnOperationFinished() {
+  if (!has_authenticated_) {
+    // If the operation finished but the device never authenticated, there was
+    // some sort of problem connecting to the device. In this case, notify
+    // observers of a failure.
+    NotifyObserversOfConnectionFailure(
+        ConnectTetheringResponse_ResponseCode::
+            ConnectTetheringResponse_ResponseCode_UNKNOWN_ERROR);
+  }
+}
+
+MessageType ConnectTetheringOperation::GetMessageTypeForConnection() {
+  return MessageType::CONNECT_TETHERING_REQUEST;
+}
+
+void ConnectTetheringOperation::NotifyObserversOfSuccessfulResponse(
+    const std::string& ssid,
+    const std::string& password) {
+  for (auto& observer : observer_list_) {
+    observer.OnSuccessfulConnectTetheringResponse(ssid, password);
+  }
+}
+
+void ConnectTetheringOperation::NotifyObserversOfConnectionFailure(
+    ConnectTetheringResponse_ResponseCode error_code) {
+  for (auto& observer : observer_list_) {
+    observer.OnConnectTetheringFailure(error_code);
+  }
+}
+
+}  // namespace tether
+
+}  // namespace chromeos
diff --git a/chromeos/components/tether/connect_tethering_operation.h b/chromeos/components/tether/connect_tethering_operation.h
new file mode 100644
index 0000000..d3e619a
--- /dev/null
+++ b/chromeos/components/tether/connect_tethering_operation.h
@@ -0,0 +1,90 @@
+// 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_CONNECT_TETHERING_OPERATION_H_
+#define CHROMEOS_COMPONENTS_TETHER_CONNECT_TETHERING_OPERATION_H_
+
+#include <map>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/observer_list.h"
+#include "chromeos/components/tether/ble_connection_manager.h"
+#include "chromeos/components/tether/message_transfer_operation.h"
+#include "components/cryptauth/remote_device.h"
+
+namespace chromeos {
+
+namespace tether {
+
+class MessageWrapper;
+
+// Operation used to request that a tether host share its Internet connection.
+// Attempts a connection to the RemoteDevice passed to its constructor and
+// notifies observers when the RemoteDevice sends a response.
+// TODO(khorimoto): Add a timeout which gives up if no response is received in
+// a reasonable amount of time.
+class ConnectTetheringOperation : public MessageTransferOperation {
+ public:
+  class Factory {
+   public:
+    static std::unique_ptr<ConnectTetheringOperation> NewInstance(
+        const cryptauth::RemoteDevice& device_to_connect,
+        BleConnectionManager* connection_manager);
+
+    static void SetInstanceForTesting(Factory* factory);
+
+   protected:
+    virtual std::unique_ptr<ConnectTetheringOperation> BuildInstance(
+        const cryptauth::RemoteDevice& devices_to_connect,
+        BleConnectionManager* connection_manager);
+
+   private:
+    static Factory* factory_instance_;
+  };
+
+  class Observer {
+   public:
+    virtual void OnSuccessfulConnectTetheringResponse(
+        const std::string& ssid,
+        const std::string& password) = 0;
+    virtual void OnConnectTetheringFailure(
+        ConnectTetheringResponse_ResponseCode error_code) = 0;
+  };
+
+  ConnectTetheringOperation(const cryptauth::RemoteDevice& device_to_connect,
+                            BleConnectionManager* connection_manager);
+  ~ConnectTetheringOperation() override;
+
+  void AddObserver(Observer* observer);
+  void RemoveObserver(Observer* observer);
+
+ protected:
+  // MessageTransferOperation:
+  void OnDeviceAuthenticated(
+      const cryptauth::RemoteDevice& remote_device) override;
+  void OnMessageReceived(std::unique_ptr<MessageWrapper> message_wrapper,
+                         const cryptauth::RemoteDevice& remote_device) override;
+  void OnOperationFinished() override;
+  MessageType GetMessageTypeForConnection() override;
+
+ private:
+  friend class ConnectTetheringOperationTest;
+
+  void NotifyObserversOfSuccessfulResponse(const std::string& ssid,
+                                           const std::string& password);
+  void NotifyObserversOfConnectionFailure(
+      ConnectTetheringResponse_ResponseCode error_code);
+
+  base::ObserverList<Observer> observer_list_;
+  bool has_authenticated_;
+
+  DISALLOW_COPY_AND_ASSIGN(ConnectTetheringOperation);
+};
+
+}  // namespace tether
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_COMPONENTS_TETHER_CONNECT_TETHERING_OPERATION_H_
diff --git a/chromeos/components/tether/connect_tethering_operation_unittest.cc b/chromeos/components/tether/connect_tethering_operation_unittest.cc
new file mode 100644
index 0000000..7cc0b451
--- /dev/null
+++ b/chromeos/components/tether/connect_tethering_operation_unittest.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 "chromeos/components/tether/connect_tethering_operation.h"
+
+#include <memory>
+#include <vector>
+
+#include "base/logging.h"
+#include "chromeos/components/tether/ble_constants.h"
+#include "chromeos/components/tether/fake_ble_connection_manager.h"
+#include "chromeos/components/tether/message_wrapper.h"
+#include "chromeos/components/tether/proto/tether.pb.h"
+#include "components/cryptauth/remote_device_test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace chromeos {
+
+namespace tether {
+
+namespace {
+
+const char kTestSsid[] = "testSsid";
+const char kTestPassword[] = "testPassword";
+
+class TestObserver : public ConnectTetheringOperation::Observer {
+ public:
+  TestObserver() : has_received_failure(false) {}
+
+  void OnSuccessfulConnectTetheringResponse(
+      const std::string& ssid,
+      const std::string& password) override {
+    this->ssid = ssid;
+    this->password = password;
+  }
+
+  void OnConnectTetheringFailure(
+      ConnectTetheringResponse_ResponseCode error_code) override {
+    has_received_failure = true;
+    this->error_code = error_code;
+  }
+
+  std::string ssid;
+  std::string password;
+
+  bool has_received_failure;
+  ConnectTetheringResponse_ResponseCode error_code;
+};
+
+std::string CreateConnectTetheringRequestString() {
+  ConnectTetheringRequest request;
+  return MessageWrapper(request).ToRawMessage();
+}
+
+DeviceStatus CreateFakeDeviceStatus() {
+  WifiStatus wifi_status;
+  wifi_status.set_status_code(
+      WifiStatus_StatusCode::WifiStatus_StatusCode_NOT_CONNECTED);
+
+  DeviceStatus device_status;
+  device_status.set_battery_percentage(75);
+  device_status.set_cell_provider("Google Fi");
+  device_status.set_connection_strength(4);
+  device_status.mutable_wifi_status()->CopyFrom(wifi_status);
+
+  return device_status;
+}
+
+std::string CreateConnectTetheringResponseString(
+    ConnectTetheringResponse_ResponseCode response_code,
+    bool use_proto_without_ssid_and_password) {
+  ConnectTetheringResponse response;
+  response.set_response_code(response_code);
+
+  // Only set SSID/password if |response_code| is SUCCESS.
+  if (!use_proto_without_ssid_and_password &&
+      response_code == ConnectTetheringResponse_ResponseCode::
+                           ConnectTetheringResponse_ResponseCode_SUCCESS) {
+    response.set_ssid(std::string(kTestSsid));
+    response.set_password(std::string(kTestPassword));
+  }
+
+  response.mutable_device_status()->CopyFrom(CreateFakeDeviceStatus());
+
+  return MessageWrapper(response).ToRawMessage();
+}
+
+}  // namespace
+
+class ConnectTetheringOperationTest : public testing::Test {
+ protected:
+  ConnectTetheringOperationTest()
+      : connect_tethering_request_string_(
+            CreateConnectTetheringRequestString()),
+        test_device_(cryptauth::GenerateTestRemoteDevices(1)[0]) {
+    // These tests are written under the assumption that there are a maximum of
+    // 3 connection attempts; they need to be edited if this value changes.
+    EXPECT_EQ(3u, MessageTransferOperation::kMaxConnectionAttemptsPerDevice);
+  }
+
+  void SetUp() override {
+    fake_ble_connection_manager_ = base::MakeUnique<FakeBleConnectionManager>();
+    test_observer_ = base::WrapUnique(new TestObserver());
+
+    operation_ = base::WrapUnique(new ConnectTetheringOperation(
+        test_device_, fake_ble_connection_manager_.get()));
+    operation_->AddObserver(test_observer_.get());
+    operation_->Initialize();
+  }
+
+  void SimulateDeviceAuthenticationAndVerifyMessageSent() {
+    operation_->OnDeviceAuthenticated(test_device_);
+
+    // Verify that the message was sent successfully.
+    std::vector<FakeBleConnectionManager::SentMessage>& sent_messages =
+        fake_ble_connection_manager_->sent_messages();
+    ASSERT_EQ(1u, sent_messages.size());
+    EXPECT_EQ(test_device_, sent_messages[0].remote_device);
+    EXPECT_EQ(connect_tethering_request_string_, sent_messages[0].message);
+  }
+
+  void SimulateResponseReceivedAndVerifyObserverCallbackInvoked(
+      ConnectTetheringResponse_ResponseCode response_code,
+      bool use_proto_without_ssid_and_password) {
+    fake_ble_connection_manager_->ReceiveMessage(
+        test_device_, CreateConnectTetheringResponseString(
+                          response_code, use_proto_without_ssid_and_password));
+
+    bool is_success_response =
+        response_code == ConnectTetheringResponse_ResponseCode::
+                             ConnectTetheringResponse_ResponseCode_SUCCESS;
+    ConnectTetheringResponse_ResponseCode expected_response_code;
+    if (is_success_response && use_proto_without_ssid_and_password) {
+      expected_response_code = ConnectTetheringResponse_ResponseCode::
+          ConnectTetheringResponse_ResponseCode_UNKNOWN_ERROR;
+    } else if (is_success_response && !use_proto_without_ssid_and_password) {
+      expected_response_code = ConnectTetheringResponse_ResponseCode::
+          ConnectTetheringResponse_ResponseCode_SUCCESS;
+    } else {
+      expected_response_code = response_code;
+    }
+
+    if (expected_response_code ==
+        ConnectTetheringResponse_ResponseCode::
+            ConnectTetheringResponse_ResponseCode_SUCCESS) {
+      EXPECT_EQ(std::string(kTestSsid), test_observer_->ssid);
+      EXPECT_EQ(std::string(kTestPassword), test_observer_->password);
+    } else {
+      EXPECT_TRUE(test_observer_->has_received_failure);
+      EXPECT_EQ(expected_response_code, test_observer_->error_code);
+    }
+  }
+
+  const std::string connect_tethering_request_string_;
+  const cryptauth::RemoteDevice test_device_;
+
+  std::unique_ptr<FakeBleConnectionManager> fake_ble_connection_manager_;
+  std::unique_ptr<TestObserver> test_observer_;
+  std::unique_ptr<ConnectTetheringOperation> operation_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ConnectTetheringOperationTest);
+};
+
+TEST_F(ConnectTetheringOperationTest, TestOperation_SuccessButInvalidResponse) {
+  SimulateDeviceAuthenticationAndVerifyMessageSent();
+  SimulateResponseReceivedAndVerifyObserverCallbackInvoked(
+      ConnectTetheringResponse_ResponseCode::
+          ConnectTetheringResponse_ResponseCode_SUCCESS,
+      true /* use_proto_without_ssid_and_password */);
+}
+
+TEST_F(ConnectTetheringOperationTest, TestOperation_SuccessWithValidResponse) {
+  SimulateDeviceAuthenticationAndVerifyMessageSent();
+  SimulateResponseReceivedAndVerifyObserverCallbackInvoked(
+      ConnectTetheringResponse_ResponseCode::
+          ConnectTetheringResponse_ResponseCode_SUCCESS,
+      false /* use_proto_without_ssid_and_password */);
+}
+
+TEST_F(ConnectTetheringOperationTest, TestOperation_UnknownError) {
+  SimulateDeviceAuthenticationAndVerifyMessageSent();
+  SimulateResponseReceivedAndVerifyObserverCallbackInvoked(
+      ConnectTetheringResponse_ResponseCode::
+          ConnectTetheringResponse_ResponseCode_UNKNOWN_ERROR,
+      false /* use_proto_without_ssid_and_password */);
+}
+
+TEST_F(ConnectTetheringOperationTest, TestOperation_ProvisioningFailed) {
+  SimulateDeviceAuthenticationAndVerifyMessageSent();
+  SimulateResponseReceivedAndVerifyObserverCallbackInvoked(
+      ConnectTetheringResponse_ResponseCode::
+          ConnectTetheringResponse_ResponseCode_PROVISIONING_FAILED,
+      false /* use_proto_without_ssid_and_password */);
+}
+
+TEST_F(ConnectTetheringOperationTest, TestCannotConnect) {
+  // Simulate the device failing to connect.
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_device_, cryptauth::SecureChannel::Status::CONNECTING);
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_device_, cryptauth::SecureChannel::Status::DISCONNECTED);
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_device_, cryptauth::SecureChannel::Status::CONNECTING);
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_device_, cryptauth::SecureChannel::Status::DISCONNECTED);
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_device_, cryptauth::SecureChannel::Status::CONNECTING);
+  fake_ble_connection_manager_->SetDeviceStatus(
+      test_device_, cryptauth::SecureChannel::Status::DISCONNECTED);
+
+  // The maximum number of connection failures has occurred.
+  EXPECT_TRUE(test_observer_->has_received_failure);
+  EXPECT_EQ(ConnectTetheringResponse_ResponseCode::
+                ConnectTetheringResponse_ResponseCode_UNKNOWN_ERROR,
+            test_observer_->error_code);
+}
+
+}  // namespace tether
+
+}  // namespace cryptauth
diff --git a/chromeos/components/tether/message_transfer_operation.h b/chromeos/components/tether/message_transfer_operation.h
index 71c91a2..28594906 100644
--- a/chromeos/components/tether/message_transfer_operation.h
+++ b/chromeos/components/tether/message_transfer_operation.h
@@ -76,6 +76,7 @@
 
  private:
   friend class MessageTransferOperationTest;
+  friend class ConnectTetheringOperationTest;
 
   static uint32_t kMaxConnectionAttemptsPerDevice;
 
diff --git a/chromeos/components/tether/tether_host_fetcher.cc b/chromeos/components/tether/tether_host_fetcher.cc
new file mode 100644
index 0000000..6f5427a
--- /dev/null
+++ b/chromeos/components/tether/tether_host_fetcher.cc
@@ -0,0 +1,111 @@
+// 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_host_fetcher.h"
+
+#include "base/bind.h"
+#include "base/memory/ptr_util.h"
+#include "components/cryptauth/cryptauth_device_manager.h"
+#include "components/cryptauth/remote_device_loader.h"
+#include "components/cryptauth/secure_message_delegate.h"
+
+namespace chromeos {
+
+namespace tether {
+
+TetherHostFetcher::TetherHostFetchRequest::TetherHostFetchRequest(
+    const TetherHostListCallback& list_callback)
+    : device_id(""), list_callback(list_callback) {}
+
+TetherHostFetcher::TetherHostFetchRequest::TetherHostFetchRequest(
+    const std::string& device_id,
+    const TetherHostCallback& single_callback)
+    : device_id(device_id), single_callback(single_callback) {}
+
+TetherHostFetcher::TetherHostFetchRequest::TetherHostFetchRequest(
+    const TetherHostFetchRequest& other)
+    : device_id(other.device_id),
+      list_callback(other.list_callback),
+      single_callback(other.single_callback) {}
+
+TetherHostFetcher::TetherHostFetchRequest::~TetherHostFetchRequest() {}
+
+TetherHostFetcher::TetherHostFetcher(
+    const std::string& user_id,
+    const std::string& user_private_key,
+    std::unique_ptr<Delegate> delegate,
+    cryptauth::CryptAuthDeviceManager* device_manager)
+    : user_id_(user_id),
+      user_private_key_(user_private_key),
+      delegate_(std::move(delegate)),
+      device_manager_(device_manager),
+      weak_ptr_factory_(this) {}
+
+TetherHostFetcher::~TetherHostFetcher() {}
+
+void TetherHostFetcher::FetchAllTetherHosts(
+    const TetherHostListCallback& callback) {
+  requests_.push_back(TetherHostFetchRequest(callback));
+  StartLoadingDevicesIfNeeded();
+}
+
+void TetherHostFetcher::FetchTetherHost(const std::string& device_id,
+                                        const TetherHostCallback& callback) {
+  requests_.push_back(TetherHostFetchRequest(device_id, callback));
+  StartLoadingDevicesIfNeeded();
+}
+
+void TetherHostFetcher::StartLoadingDevicesIfNeeded() {
+  if (remote_device_loader_) {
+    // If the loader is already active, there is nothing to do.
+    return;
+  }
+
+  remote_device_loader_ = cryptauth::RemoteDeviceLoader::Factory::NewInstance(
+      device_manager_->GetTetherHosts(), user_id_, user_private_key_,
+      delegate_->CreateSecureMessageDelegate());
+  remote_device_loader_->Load(
+      base::Bind(&TetherHostFetcher::OnRemoteDevicesLoaded,
+                 weak_ptr_factory_.GetWeakPtr()));
+}
+
+void TetherHostFetcher::OnRemoteDevicesLoaded(
+    const cryptauth::RemoteDeviceList& remote_devices) {
+  // Make a copy of the list before deleting |remote_device_loader_|.
+  cryptauth::RemoteDeviceList remote_devices_copy = remote_devices;
+  remote_device_loader_.reset();
+
+  // Make a copy of the requests to ensure that if one of the callbacks makes a
+  // new fetch request, it does not affect the iteration of requests.
+  std::vector<TetherHostFetchRequest> requests = requests_;
+  requests_.clear();
+
+  for (auto& request : requests) {
+    if (request.device_id.empty()) {
+      DCHECK(!request.list_callback.is_null());
+
+      request.list_callback.Run(remote_devices);
+      continue;
+    }
+
+    DCHECK(!request.single_callback.is_null());
+    bool has_run_callback = false;
+    for (const auto& remote_device : remote_devices_copy) {
+      if (request.device_id == remote_device.GetDeviceId()) {
+        has_run_callback = true;
+        request.single_callback.Run(
+            base::MakeUnique<cryptauth::RemoteDevice>(remote_device));
+        break;
+      }
+    }
+
+    if (!has_run_callback) {
+      request.single_callback.Run(nullptr);
+    }
+  }
+}
+
+}  // namespace tether
+
+}  // namespace chromeos
diff --git a/chromeos/components/tether/tether_host_fetcher.h b/chromeos/components/tether/tether_host_fetcher.h
new file mode 100644
index 0000000..e176c810
--- /dev/null
+++ b/chromeos/components/tether/tether_host_fetcher.h
@@ -0,0 +1,93 @@
+// 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_HOST_FETCHER_H_
+#define CHROMEOS_COMPONENTS_TETHER_TETHER_HOST_FETCHER_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "base/memory/weak_ptr.h"
+#include "components/cryptauth/remote_device.h"
+
+namespace cryptauth {
+class CryptAuthDeviceManager;
+class RemoteDeviceLoader;
+class SecureMessageDelegate;
+}  // namespace cryptauth
+
+namespace chromeos {
+
+namespace tether {
+
+// Fetches RemoteDevice objects corresponding to tether hosts which have been
+// synced via CryptAuth.
+class TetherHostFetcher {
+ public:
+  class Delegate {
+   public:
+    virtual std::unique_ptr<cryptauth::SecureMessageDelegate>
+    CreateSecureMessageDelegate() = 0;
+  };
+
+  TetherHostFetcher(const std::string& user_id,
+                    const std::string& user_private_key,
+                    std::unique_ptr<Delegate> delegate,
+                    cryptauth::CryptAuthDeviceManager* device_manager);
+  virtual ~TetherHostFetcher();
+
+  // Fetches all tether hosts.
+  using TetherHostListCallback =
+      base::Callback<void(const cryptauth::RemoteDeviceList&)>;
+  virtual void FetchAllTetherHosts(const TetherHostListCallback& callback);
+
+  // Fetches the tether host with the ID |device_id|.
+  using TetherHostCallback =
+      base::Callback<void(std::unique_ptr<cryptauth::RemoteDevice>)>;
+  virtual void FetchTetherHost(const std::string& device_id,
+                               const TetherHostCallback& callback);
+
+ private:
+  struct TetherHostFetchRequest {
+    TetherHostFetchRequest(const TetherHostListCallback& list_callback);
+    TetherHostFetchRequest(const std::string& device_id,
+                           const TetherHostCallback& single_callback);
+    TetherHostFetchRequest(const TetherHostFetchRequest& other);
+    ~TetherHostFetchRequest();
+
+    std::string device_id;
+
+    // Only one of the two callbacks is actually used depending on which
+    // constructor is used. If a device ID is provided, then the request is for
+    // a single device, and |single_callback| is used; otherwise, the request is
+    // for all devices, so |list_callback| is used.
+    TetherHostListCallback list_callback;
+    TetherHostCallback single_callback;
+  };
+
+  void StartLoadingDevicesIfNeeded();
+  void OnRemoteDevicesLoaded(const cryptauth::RemoteDeviceList& remote_devices);
+
+  const std::string user_id_;
+  const std::string user_private_key_;
+  std::unique_ptr<Delegate> delegate_;
+  cryptauth::CryptAuthDeviceManager* device_manager_;
+
+  std::vector<TetherHostFetchRequest> requests_;
+
+  std::unique_ptr<cryptauth::RemoteDeviceLoader> remote_device_loader_;
+
+  base::WeakPtrFactory<TetherHostFetcher> weak_ptr_factory_;
+
+  DISALLOW_COPY_AND_ASSIGN(TetherHostFetcher);
+};
+
+}  // namespace tether
+
+}  // namespace chromeos
+
+#endif  // CHROMEOS_COMPONENTS_TETHER_TETHER_HOST_FETCHER_H_
diff --git a/chromeos/components/tether/tether_host_fetcher_unittest.cc b/chromeos/components/tether/tether_host_fetcher_unittest.cc
new file mode 100644
index 0000000..01c5755
--- /dev/null
+++ b/chromeos/components/tether/tether_host_fetcher_unittest.cc
@@ -0,0 +1,265 @@
+// 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 "chromeos/components/tether/tether_host_fetcher.h"
+
+#include <memory>
+#include <vector>
+
+#include "base/bind.h"
+#include "base/memory/ptr_util.h"
+#include "components/cryptauth/cryptauth_device_manager.h"
+#include "components/cryptauth/fake_secure_message_delegate.h"
+#include "components/cryptauth/proto/cryptauth_api.pb.h"
+#include "components/cryptauth/remote_device_loader.h"
+#include "components/cryptauth/remote_device_test_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using testing::_;
+using testing::Invoke;
+using testing::NiceMock;
+using testing::Return;
+
+namespace chromeos {
+
+namespace tether {
+
+namespace {
+
+const char kTestUserId[] = "testUserId";
+const char kTestUserPrivateKey[] = "kTestUserPrivateKey";
+
+class TestDelegate : public TetherHostFetcher::Delegate {
+ public:
+  std::unique_ptr<cryptauth::SecureMessageDelegate>
+  CreateSecureMessageDelegate() override {
+    cryptauth::FakeSecureMessageDelegate* delegate =
+        new cryptauth::FakeSecureMessageDelegate();
+    created_delegates_.push_back(delegate);
+    return base::WrapUnique(delegate);
+  }
+
+  void VerifySecureMessageDelegateCreatedByFactory(
+      cryptauth::FakeSecureMessageDelegate* delegate) {
+    EXPECT_FALSE(std::find(created_delegates_.begin(), created_delegates_.end(),
+                           delegate) == created_delegates_.end());
+  }
+
+ private:
+  std::vector<cryptauth::FakeSecureMessageDelegate*> created_delegates_;
+};
+
+class MockDeviceManager : public cryptauth::CryptAuthDeviceManager {
+ public:
+  ~MockDeviceManager() override {}
+
+  MOCK_CONST_METHOD0(GetTetherHosts,
+                     std::vector<cryptauth::ExternalDeviceInfo>());
+};
+
+class MockDeviceLoader : public cryptauth::RemoteDeviceLoader {
+ public:
+  MockDeviceLoader()
+      : cryptauth::RemoteDeviceLoader(
+            std::vector<cryptauth::ExternalDeviceInfo>(),
+            "",
+            "",
+            nullptr) {}
+  ~MockDeviceLoader() override {}
+
+  MOCK_METHOD1(
+      Load,
+      void(const cryptauth::RemoteDeviceLoader::RemoteDeviceCallback&));
+};
+
+std::vector<cryptauth::ExternalDeviceInfo>
+CreateTetherExternalDeviceInfosForRemoteDevices(
+    const std::vector<cryptauth::RemoteDevice> remote_devices) {
+  std::vector<cryptauth::ExternalDeviceInfo> device_infos;
+  for (const auto& remote_device : remote_devices) {
+    // Add an ExternalDeviceInfo with the same public key as the RemoteDevice.
+    cryptauth::ExternalDeviceInfo info;
+    info.set_public_key(remote_device.public_key);
+    device_infos.push_back(info);
+  }
+  return device_infos;
+}
+
+}  // namespace
+
+class TetherHostFetcherTest : public testing::Test {
+ public:
+  class TestRemoteDeviceLoaderFactory
+      : public cryptauth::RemoteDeviceLoader::Factory {
+   public:
+    TestRemoteDeviceLoaderFactory(TetherHostFetcherTest* test) : test_(test) {}
+
+    std::unique_ptr<cryptauth::RemoteDeviceLoader> BuildInstance(
+        const std::vector<cryptauth::ExternalDeviceInfo>& device_info_list,
+        const std::string& user_id,
+        const std::string& user_private_key,
+        std::unique_ptr<cryptauth::SecureMessageDelegate>
+            secure_message_delegate) override {
+      EXPECT_EQ(test_->test_device_infos_.size(), device_info_list.size());
+      EXPECT_EQ(std::string(kTestUserId), user_id);
+      EXPECT_EQ(std::string(kTestUserPrivateKey), user_private_key);
+      test_->test_delegate_->VerifySecureMessageDelegateCreatedByFactory(
+          static_cast<cryptauth::FakeSecureMessageDelegate*>(
+              secure_message_delegate.get()));
+
+      std::unique_ptr<MockDeviceLoader> device_loader =
+          base::WrapUnique(new NiceMock<MockDeviceLoader>());
+      ON_CALL(*device_loader, Load(_))
+          .WillByDefault(
+              Invoke(this, &TestRemoteDeviceLoaderFactory::MockLoadImpl));
+      return std::move(device_loader);
+    }
+
+    void MockLoadImpl(
+        const cryptauth::RemoteDeviceLoader::RemoteDeviceCallback& callback) {
+      callback_ = callback;
+    }
+
+    void InvokeLastCallback() {
+      DCHECK(!callback_.is_null());
+      callback_.Run(test_->test_devices_);
+    }
+
+   private:
+    cryptauth::RemoteDeviceLoader::RemoteDeviceCallback callback_;
+    TetherHostFetcherTest* test_;
+  };
+
+  TetherHostFetcherTest()
+      : test_devices_(cryptauth::GenerateTestRemoteDevices(5)),
+        test_device_infos_(
+            CreateTetherExternalDeviceInfosForRemoteDevices(test_devices_)) {}
+
+  void SetUp() override {
+    device_list_list_.clear();
+    single_device_list_.clear();
+
+    std::unique_ptr<TestDelegate> test_delegate =
+        base::WrapUnique(new TestDelegate());
+    test_delegate_ = test_delegate.get();
+
+    mock_device_manager_ = base::WrapUnique(new NiceMock<MockDeviceManager>());
+    ON_CALL(*mock_device_manager_, GetTetherHosts())
+        .WillByDefault(Return(test_device_infos_));
+
+    test_device_loader_factory_ =
+        base::WrapUnique(new TestRemoteDeviceLoaderFactory(this));
+    cryptauth::RemoteDeviceLoader::Factory::SetInstanceForTesting(
+        test_device_loader_factory_.get());
+
+    tether_host_fetcher_ = base::MakeUnique<TetherHostFetcher>(
+        std::string(kTestUserId), std::string(kTestUserPrivateKey),
+        std::move(test_delegate), mock_device_manager_.get());
+  }
+
+  void OnTetherHostListFetched(const cryptauth::RemoteDeviceList& device_list) {
+    device_list_list_.push_back(device_list);
+  }
+
+  void OnSingleTetherHostFetched(
+      std::unique_ptr<cryptauth::RemoteDevice> device) {
+    single_device_list_.push_back(std::move(device));
+  }
+
+  const std::vector<cryptauth::RemoteDevice> test_devices_;
+  const std::vector<cryptauth::ExternalDeviceInfo> test_device_infos_;
+
+  std::vector<cryptauth::RemoteDeviceList> device_list_list_;
+  std::vector<std::shared_ptr<cryptauth::RemoteDevice>> single_device_list_;
+
+  TestDelegate* test_delegate_;
+  std::unique_ptr<NiceMock<MockDeviceManager>> mock_device_manager_;
+  std::unique_ptr<TestRemoteDeviceLoaderFactory> test_device_loader_factory_;
+
+  std::unique_ptr<TetherHostFetcher> tether_host_fetcher_;
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TetherHostFetcherTest);
+};
+
+TEST_F(TetherHostFetcherTest, TestFetchAllTetherHosts) {
+  tether_host_fetcher_->FetchAllTetherHosts(base::Bind(
+      &TetherHostFetcherTest::OnTetherHostListFetched, base::Unretained(this)));
+
+  // Nothing should load until the callback is invoked.
+  EXPECT_EQ(0u, device_list_list_.size());
+  EXPECT_EQ(0u, single_device_list_.size());
+
+  test_device_loader_factory_->InvokeLastCallback();
+
+  EXPECT_EQ(1u, device_list_list_.size());
+  EXPECT_EQ(test_devices_, device_list_list_[0]);
+  EXPECT_EQ(0u, single_device_list_.size());
+}
+
+TEST_F(TetherHostFetcherTest, TestSingleTetherHost) {
+  tether_host_fetcher_->FetchTetherHost(
+      test_devices_[0].GetDeviceId(),
+      base::Bind(&TetherHostFetcherTest::OnSingleTetherHostFetched,
+                 base::Unretained(this)));
+
+  // Nothing should load until the callback is invoked.
+  EXPECT_EQ(0u, device_list_list_.size());
+  EXPECT_EQ(0u, single_device_list_.size());
+
+  test_device_loader_factory_->InvokeLastCallback();
+
+  EXPECT_EQ(0u, device_list_list_.size());
+  EXPECT_EQ(1u, single_device_list_.size());
+  EXPECT_EQ(test_devices_[0], *single_device_list_[0]);
+}
+
+TEST_F(TetherHostFetcherTest,
+       TestSingleTetherHost_IdDoesNotCorrespondToDevice) {
+  tether_host_fetcher_->FetchTetherHost(
+      "idWhichDoesNotCorrespondToADevice",
+      base::Bind(&TetherHostFetcherTest::OnSingleTetherHostFetched,
+                 base::Unretained(this)));
+
+  // Nothing should load until the callback is invoked.
+  EXPECT_EQ(0u, device_list_list_.size());
+  EXPECT_EQ(0u, single_device_list_.size());
+
+  test_device_loader_factory_->InvokeLastCallback();
+
+  EXPECT_EQ(0u, device_list_list_.size());
+  EXPECT_EQ(1u, single_device_list_.size());
+  EXPECT_EQ(nullptr, single_device_list_[0]);
+}
+
+TEST_F(TetherHostFetcherTest, TestMultipleSimultaneousRequests) {
+  // Make the requests in the three previous tests at the same time.
+  tether_host_fetcher_->FetchAllTetherHosts(base::Bind(
+      &TetherHostFetcherTest::OnTetherHostListFetched, base::Unretained(this)));
+  tether_host_fetcher_->FetchTetherHost(
+      test_devices_[0].GetDeviceId(),
+      base::Bind(&TetherHostFetcherTest::OnSingleTetherHostFetched,
+                 base::Unretained(this)));
+  tether_host_fetcher_->FetchTetherHost(
+      "idWhichDoesNotCorrespondToADevice",
+      base::Bind(&TetherHostFetcherTest::OnSingleTetherHostFetched,
+                 base::Unretained(this)));
+
+  // Nothing should load until the callback is invoked.
+  EXPECT_EQ(0u, device_list_list_.size());
+  EXPECT_EQ(0u, single_device_list_.size());
+
+  test_device_loader_factory_->InvokeLastCallback();
+
+  EXPECT_EQ(1u, device_list_list_.size());
+  EXPECT_EQ(test_devices_, device_list_list_[0]);
+  EXPECT_EQ(2u, single_device_list_.size());
+  EXPECT_EQ(test_devices_[0], *single_device_list_[0]);
+  EXPECT_EQ(nullptr, single_device_list_[1]);
+}
+
+}  // namespace tether
+
+}  // namespace cryptauth
diff --git a/components/arc/BUILD.gn b/components/arc/BUILD.gn
index 9623523e..8ff0e78 100644
--- a/components/arc/BUILD.gn
+++ b/components/arc/BUILD.gn
@@ -64,7 +64,7 @@
 
   deps = [
     "//ash:ash",
-    "//ash/public/interfaces",
+    "//ash/public/cpp:ash_public_cpp",
     "//base",
     "//chromeos",
     "//chromeos:power_manager_proto",
diff --git a/components/autofill/OWNERS b/components/autofill/OWNERS
index a82a7a3..585db25e 100644
--- a/components/autofill/OWNERS
+++ b/components/autofill/OWNERS
@@ -8,3 +8,5 @@
 # TODO(gcasto): Change to per-file ownership after http://crbug.com/235756
 # is fixed.
 gcasto@chromium.org
+
+# COMPONENT: UI>Browser>Autofill
diff --git a/components/browser_watcher/postmortem_report_collector.cc b/components/browser_watcher/postmortem_report_collector.cc
index 7f5bf145..837f023 100644
--- a/components/browser_watcher/postmortem_report_collector.cc
+++ b/components/browser_watcher/postmortem_report_collector.cc
@@ -170,6 +170,8 @@
   // Collect the list of files to harvest.
   std::vector<FilePath> debug_files = GetDebugStateFilePaths(
       debug_info_dir, debug_file_pattern, excluded_debug_files);
+  UMA_HISTOGRAM_COUNTS_100("ActivityTracker.Collect.StabilityFileCount",
+                           debug_files.size());
 
   // Determine the crashpad client id.
   crashpad::UUID client_id;
@@ -232,7 +234,7 @@
     // The file was empty, or there was an error collecting the data. Detailed
     // logging happens within the Collect function.
     if (!base::DeleteFile(file, false))
-      LOG(ERROR) << "Failed to delete " << file.value();
+      DLOG(ERROR) << "Failed to delete " << file.value();
     return status;
   }
   DCHECK_NE(nullptr, report_proto.get());
@@ -242,7 +244,8 @@
   CrashReportDatabase::OperationStatus database_status =
       report_database->PrepareNewCrashReport(&new_report);
   if (database_status != CrashReportDatabase::kNoError) {
-    LOG(ERROR) << "PrepareNewCrashReport failed";
+    // Assume this is recoverable: not deleting the file.
+    DLOG(ERROR) << "PrepareNewCrashReport failed";
     return PREPARE_NEW_CRASH_REPORT_FAILED;
   }
   CrashReportDatabase::CallErrorWritingCrashReport
@@ -251,6 +254,9 @@
   // Write the report to a minidump.
   if (!WriteReportToMinidump(report_proto.get(), client_id, new_report->uuid,
                              reinterpret_cast<FILE*>(new_report->handle))) {
+    // Assume this is not recoverable and delete the file.
+    if (!base::DeleteFile(file, false))
+      DLOG(ERROR) << "Failed to delete " << file.value();
     return WRITE_TO_MINIDUMP_FAILED;
   }
 
@@ -260,7 +266,7 @@
   // cannot be deleted.
   // TODO(manzagop): metrics for the number of non-deletable files.
   if (!base::DeleteFile(file, false)) {
-    LOG(ERROR) << "Failed to delete " << file.value();
+    DLOG(ERROR) << "Failed to delete " << file.value();
     return DEBUG_FILE_DELETION_FAILED;
   }
 
@@ -272,7 +278,7 @@
   database_status = report_database->FinishedWritingCrashReport(
       new_report, &unused_report_id);
   if (database_status != CrashReportDatabase::kNoError) {
-    LOG(ERROR) << "FinishedWritingCrashReport failed";
+    DLOG(ERROR) << "FinishedWritingCrashReport failed";
     return FINISHED_WRITING_CRASH_REPORT_FAILED;
   }
 
diff --git a/components/cryptauth/remote_device_loader.h b/components/cryptauth/remote_device_loader.h
index e4adcec..5ef6394 100644
--- a/components/cryptauth/remote_device_loader.h
+++ b/components/cryptauth/remote_device_loader.h
@@ -59,12 +59,12 @@
       std::unique_ptr<cryptauth::SecureMessageDelegate>
           secure_message_delegate);
 
-  ~RemoteDeviceLoader();
+  virtual ~RemoteDeviceLoader();
 
   // Loads the RemoteDevice objects. |callback| will be invoked upon completion.
   typedef base::Callback<void(const cryptauth::RemoteDeviceList&)>
       RemoteDeviceCallback;
-  void Load(const RemoteDeviceCallback& callback);
+  virtual void Load(const RemoteDeviceCallback& callback);
 
  private:
   // Called when the PSK is derived for each device. If the PSKs for all devices
diff --git a/components/exo/wayland/BUILD.gn b/components/exo/wayland/BUILD.gn
index 8506c92a..5f6bb62 100644
--- a/components/exo/wayland/BUILD.gn
+++ b/components/exo/wayland/BUILD.gn
@@ -111,9 +111,9 @@
   }
 }
 
-executable("wayland_motion_events") {
+executable("wayland_rects_client") {
   sources = [
-    "clients/motion_events.cc",
+    "clients/rects.cc",
   ]
 
   deps = [
@@ -139,7 +139,7 @@
 
 executable("wayland_simple_client") {
   sources = [
-    "clients/simple_client.cc",
+    "clients/simple.cc",
   ]
 
   deps = [
diff --git a/components/exo/wayland/clients/motion_events.cc b/components/exo/wayland/clients/rects.cc
similarity index 97%
rename from components/exo/wayland/clients/motion_events.cc
rename to components/exo/wayland/clients/rects.cc
index eabab2f..342d8e66 100644
--- a/components/exo/wayland/clients/motion_events.cc
+++ b/components/exo/wayland/clients/rects.cc
@@ -204,11 +204,11 @@
 }  // namespace
 
 ////////////////////////////////////////////////////////////////////////////////
-// MotionEvents:
+// RectsClient:
 
-class MotionEvents : public ClientBase {
+class RectsClient : public ClientBase {
  public:
-  MotionEvents() {}
+  RectsClient() {}
 
   // Initialize and run client main loop.
   int Run(const ClientBase::InitParams& params,
@@ -219,15 +219,15 @@
           bool show_fps_counter);
 
  private:
-  DISALLOW_COPY_AND_ASSIGN(MotionEvents);
+  DISALLOW_COPY_AND_ASSIGN(RectsClient);
 };
 
-int MotionEvents::Run(const ClientBase::InitParams& params,
-                      size_t max_frames_pending,
-                      size_t num_rects,
-                      size_t num_benchmark_runs,
-                      base::TimeDelta benchmark_interval,
-                      bool show_fps_counter) {
+int RectsClient::Run(const ClientBase::InitParams& params,
+                     size_t max_frames_pending,
+                     size_t num_rects,
+                     size_t num_benchmark_runs,
+                     base::TimeDelta benchmark_interval,
+                     bool show_fps_counter) {
   if (!ClientBase::Init(params))
     return 1;
 
@@ -520,7 +520,7 @@
     return 1;
   }
 
-  exo::wayland::clients::MotionEvents client;
+  exo::wayland::clients::RectsClient client;
   return client.Run(params, max_frames_pending, num_rects, num_benchmark_runs,
                     base::TimeDelta::FromMilliseconds(benchmark_interval_ms),
                     command_line->HasSwitch(switches::kShowFpsCounter));
diff --git a/components/exo/wayland/clients/simple_client.cc b/components/exo/wayland/clients/simple.cc
similarity index 100%
rename from components/exo/wayland/clients/simple_client.cc
rename to components/exo/wayland/clients/simple.cc
diff --git a/components/image_fetcher/OWNERS b/components/image_fetcher/OWNERS
index 26c1c25c..88fe2d2 100644
--- a/components/image_fetcher/OWNERS
+++ b/components/image_fetcher/OWNERS
@@ -1,3 +1,5 @@
 markusheintz@chromium.org
 mathp@chromium.org
 treib@chromium.org
+
+# COMPONENT: Internals>Images
diff --git a/components/leveldb_proto/OWNERS b/components/leveldb_proto/OWNERS
index b68a752..f473a87 100644
--- a/components/leveldb_proto/OWNERS
+++ b/components/leveldb_proto/OWNERS
@@ -1,2 +1,4 @@
 mathp@chromium.org
 nyquist@chromium.org
+
+# COMPONENT: Internals
diff --git a/components/metrics/proto/BUILD.gn b/components/metrics/proto/BUILD.gn
index 1a2e4d0b..d8f8c1fd 100644
--- a/components/metrics/proto/BUILD.gn
+++ b/components/metrics/proto/BUILD.gn
@@ -20,6 +20,7 @@
     "sampled_profile.proto",
     "system_profile.proto",
     "translate_event.proto",
+    "ukm/entry.proto",
     "ukm/report.proto",
     "ukm/source.proto",
     "user_action_event.proto",
diff --git a/components/metrics/proto/ukm/entry.proto b/components/metrics/proto/ukm/entry.proto
new file mode 100644
index 0000000..22385c8
--- /dev/null
+++ b/components/metrics/proto/ukm/entry.proto
@@ -0,0 +1,37 @@
+// 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.
+
+syntax = "proto2";
+
+package ukm;
+
+option optimize_for = LITE_RUNTIME;
+
+// Next tag: 6
+message Entry {
+  // Unique identifier for an Event. This is used to provide hierarchical
+  // structure for Events.
+  optional int32 id = 1;
+
+  // Parent id, which is associated with an id for another Event. This is set
+  // only if the Event has another Event which can be considered a parent.
+  // This is to provide hierarchies for Events.
+  optional int32 parent_id = 2;
+
+  // The id of the Source this Event is associated with.
+  optional int32 source_id = 3;
+
+  // Type of the Event. This is a hash of the name (as a string).
+  optional fixed64 event_hash = 4;
+
+  // For each Event, we have a list of possible metrics included. It's possible
+  // for a single metric name to be repeated. There is also no guarentee that
+  // all metrics that are available for a given event will be provided for a
+  // single Entry.
+  message Metric {
+    optional fixed64 metric_hash = 1;
+    optional int64 value = 2;
+  }
+  repeated Metric metrics = 5;
+}
diff --git a/components/metrics/proto/ukm/report.proto b/components/metrics/proto/ukm/report.proto
index 9ae9eff..c9133552c 100644
--- a/components/metrics/proto/ukm/report.proto
+++ b/components/metrics/proto/ukm/report.proto
@@ -8,11 +8,12 @@
 
 option optimize_for = LITE_RUNTIME;
 
+import "ukm/entry.proto";
 import "ukm/source.proto";
 import "system_profile.proto";
 
 // This is the message type sent from Chrome to the UKM collector.
-// Next tag: 4
+// Next tag: 5
 message Report {
   // A unique identifier for a Chrome install. This ID should be used only
   // in UKM reports, and not linked to any other data sources.
@@ -23,4 +24,7 @@
 
   // A list of the top-level navigations that data was collected for.
   repeated Source sources = 3;
+
+  // List of Entries containing the main UKM data.
+  repeated Entry entries = 4;
 }
diff --git a/components/metrics/proto/ukm/source.proto b/components/metrics/proto/ukm/source.proto
index e48f252..165083bf 100644
--- a/components/metrics/proto/ukm/source.proto
+++ b/components/metrics/proto/ukm/source.proto
@@ -9,17 +9,19 @@
 option optimize_for = LITE_RUNTIME;
 
 // Source contains data related to a top-level navigation.
-// Next tag: 5
+// Next tag: 6
 message Source {
-  // A identifier for the source. This should be unique even across sessions.
+  // An identifier for the source. This should be unique within a session.
   optional int32 id = 1;
 
-  // The url of the source, as recorded in history.  If this URL has not been
-  // discovered by Google's crawler, it must be stripped to the security origin
-  // before recording to logs.  If the security origin has not been discovered
-  // by the crawler, the security origin must not be logged.
+  // The URL of the source, as recorded in history. If this URL has not been
+  // discovered by Google's crawler, it should not be recorded.
   optional string url = 2;
 
+  // The origin of the URL. This is reserved to be used by server side only.
+  reserved 5;
+  reserved "url_origin";
+
   // Timestamp of navigation to this Source, as seen by the client. Time of
   // events related to this Source will generally be relative to this timestamp.
   optional int64 navigation_time_msec = 3;
diff --git a/components/omnibox/browser/autocomplete_result.cc b/components/omnibox/browser/autocomplete_result.cc
index 2dd7aad..bc51bd4 100644
--- a/components/omnibox/browser/autocomplete_result.cc
+++ b/components/omnibox/browser/autocomplete_result.cc
@@ -94,7 +94,7 @@
     matches_.push_back(i);
     if (!AutocompleteMatch::IsSearchType(i.type)) {
       const OmniboxFieldTrial::EmphasizeTitlesCondition condition(
-          OmniboxFieldTrial::GetEmphasizeTitlesConditionForInput(input.type()));
+          OmniboxFieldTrial::GetEmphasizeTitlesConditionForInput(input));
       bool emphasize = false;
       switch (condition) {
         case OmniboxFieldTrial::EMPHASIZE_WHEN_NONEMPTY:
diff --git a/components/omnibox/browser/features.cc b/components/omnibox/browser/features.cc
index 4ab8d4a..a98e150 100644
--- a/components/omnibox/browser/features.cc
+++ b/components/omnibox/browser/features.cc
@@ -10,4 +10,9 @@
 const base::Feature kZeroSuggestRedirectToChrome{
     "ZeroSuggestRedirectToChrome", base::FEATURE_DISABLED_BY_DEFAULT};
 
+// Feature used to swap the title and URL when providing zero suggest
+// suggestions.
+const base::Feature kZeroSuggestSwapTitleAndUrl{
+    "ZeroSuggestSwapTitleAndUrl", base::FEATURE_DISABLED_BY_DEFAULT};
+
 }  // namespace features
diff --git a/components/omnibox/browser/features.h b/components/omnibox/browser/features.h
index 06b9d2a..8820b72a 100644
--- a/components/omnibox/browser/features.h
+++ b/components/omnibox/browser/features.h
@@ -11,6 +11,8 @@
 
 extern const base::Feature kZeroSuggestRedirectToChrome;
 
+extern const base::Feature kZeroSuggestSwapTitleAndUrl;
+
 }  // namespace features
 
 #endif  // COMPONENTS_OMNIBOX_BROWSER_FEATURES_H_
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc
index c959a0f..f1fa8e047 100644
--- a/components/omnibox/browser/omnibox_field_trial.cc
+++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -539,14 +539,19 @@
 
 OmniboxFieldTrial::EmphasizeTitlesCondition
 OmniboxFieldTrial::GetEmphasizeTitlesConditionForInput(
-    metrics::OmniboxInputType::Type input_type) {
-  // Look up the parameter named kEmphasizeTitlesRule + ":" + input_type,
+    const AutocompleteInput& input) {
+  // First, check if we should emphasize titles for zero suggest suggestions.
+  if (input.from_omnibox_focus() &&
+      base::FeatureList::IsEnabled(features::kZeroSuggestSwapTitleAndUrl)) {
+    return EMPHASIZE_WHEN_NONEMPTY;
+  }
+  // Look up the parameter named kEmphasizeTitlesRule + ":" + input.type(),
   // find its value, and return that value as an enum.  If the parameter
   // isn't redefined, fall back to the generic rule kEmphasizeTitlesRule + ":*"
   std::string value_str(variations::GetVariationParamValue(
       kBundledExperimentFieldTrialName,
       std::string(kEmphasizeTitlesRule) + "_" +
-      base::IntToString(static_cast<int>(input_type))));
+          base::IntToString(static_cast<int>(input.type()))));
   if (value_str.empty()) {
     value_str = variations::GetVariationParamValue(
         kBundledExperimentFieldTrialName,
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h
index e0edee7..808ab7c 100644
--- a/components/omnibox/browser/omnibox_field_trial.h
+++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -14,7 +14,7 @@
 
 #include "base/macros.h"
 #include "components/metrics/proto/omnibox_event.pb.h"
-#include "components/metrics/proto/omnibox_input_type.pb.h"
+#include "components/omnibox/browser/autocomplete_input.h"
 #include "components/omnibox/browser/autocomplete_match_type.h"
 
 namespace base {
@@ -375,11 +375,11 @@
   // field trial.
 
   // Returns the conditions under which the UI code should display the title
-  // of a URL more prominently than the URL for an input of type |input_type|.
-  // Normally the URL is displayed more prominently.  Returns NEVER_EMPHASIZE
-  // if the experiment isn't active.
+  // of a URL more prominently than the URL for input |input|. Normally the URL
+  // is displayed more prominently. Returns NEVER_EMPHASIZE if the experiment
+  // isn't active.
   static EmphasizeTitlesCondition GetEmphasizeTitlesConditionForInput(
-      metrics::OmniboxInputType::Type input_type);
+      const AutocompleteInput& input);
 
   // ---------------------------------------------------------
   // For PhysicalWebProvider related experiments.
@@ -405,8 +405,8 @@
   // For experiment redirecting zero suggest requests to a service provided by
   // the Chrome team.
 
-  // Returns whether the user is in the field trial which redirects zero suggest
-  // requests to the service provided by the Chrome team.
+  // Returns true whether the user is in the field trial which redirects zero
+  // suggest requests to the service provided by the Chrome team.
   static bool InZeroSuggestRedirectToChromeFieldTrial();
 
   // Returns a string representing the address of the server where the zero
diff --git a/components/password_manager/core/browser/affiliated_match_helper.cc b/components/password_manager/core/browser/affiliated_match_helper.cc
index 191edb36..b88033a 100644
--- a/components/password_manager/core/browser/affiliated_match_helper.cc
+++ b/components/password_manager/core/browser/affiliated_match_helper.cc
@@ -33,13 +33,12 @@
 }  // namespace
 
 // static
-const int64_t AffiliatedMatchHelper::kInitializationDelayOnStartupInSeconds;
+constexpr base::TimeDelta AffiliatedMatchHelper::kInitializationDelayOnStartup;
 
 AffiliatedMatchHelper::AffiliatedMatchHelper(
     PasswordStore* password_store,
     std::unique_ptr<AffiliationService> affiliation_service)
     : password_store_(password_store),
-      task_runner_for_waiting_(base::ThreadTaskRunnerHandle::Get()),
       affiliation_service_(std::move(affiliation_service)),
       weak_ptr_factory_(this) {}
 
@@ -51,10 +50,11 @@
 void AffiliatedMatchHelper::Initialize() {
   DCHECK(password_store_);
   DCHECK(affiliation_service_);
-  task_runner_for_waiting_->PostDelayedTask(
-      FROM_HERE, base::Bind(&AffiliatedMatchHelper::DoDeferredInitialization,
-                            weak_ptr_factory_.GetWeakPtr()),
-      base::TimeDelta::FromSeconds(kInitializationDelayOnStartupInSeconds));
+  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&AffiliatedMatchHelper::DoDeferredInitialization,
+                 weak_ptr_factory_.GetWeakPtr()),
+      kInitializationDelayOnStartup);
 }
 
 void AffiliatedMatchHelper::GetAffiliatedAndroidRealms(
@@ -144,11 +144,6 @@
          facet_uri.IsValidWebFacetURI();
 }
 
-void AffiliatedMatchHelper::SetTaskRunnerUsedForWaitingForTesting(
-    const scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
-  task_runner_for_waiting_ = task_runner;
-}
-
 void AffiliatedMatchHelper::DoDeferredInitialization() {
   // Must start observing for changes at the same time as when the snapshot is
   // taken to avoid inconsistencies due to any changes taking place in-between.
diff --git a/components/password_manager/core/browser/affiliated_match_helper.h b/components/password_manager/core/browser/affiliated_match_helper.h
index 7e51c96..50c7fd2 100644
--- a/components/password_manager/core/browser/affiliated_match_helper.h
+++ b/components/password_manager/core/browser/affiliated_match_helper.h
@@ -5,8 +5,6 @@
 #ifndef COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_AFFILIATED_MATCH_HELPER_H_
 #define COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_AFFILIATED_MATCH_HELPER_H_
 
-#include <stdint.h>
-
 #include <memory>
 #include <string>
 #include <vector>
@@ -14,6 +12,7 @@
 #include "base/callback_forward.h"
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
+#include "base/time/time.h"
 #include "components/password_manager/core/browser/affiliation_utils.h"
 #include "components/password_manager/core/browser/password_store.h"
 #include "components/password_manager/core/browser/password_store_consumer.h"
@@ -100,17 +99,13 @@
   // purposes of affiliation-based matching.
   static bool IsValidWebCredential(const PasswordStore::FormDigest& form);
 
-  // Sets the task runner to be used to delay I/O heavy initialization. Should
-  // be called before Initialize(). Used only for testing.
-  void SetTaskRunnerUsedForWaitingForTesting(
-      const scoped_refptr<base::SingleThreadTaskRunner> task_runner);
-
   // I/O heavy initialization on start-up will be delayed by this long.
   // This should be high enough not to exacerbate start-up I/O contention too
   // much, but also low enough that the user be able log-in shortly after
   // browser start-up into web sites using Android credentials.
   // TODO(engedy): See if we can tie this instead to some meaningful event.
-  static const int64_t kInitializationDelayOnStartupInSeconds = 8;
+  static constexpr base::TimeDelta kInitializationDelayOnStartup =
+      base::TimeDelta::FromSeconds(8);
 
  private:
   // Reads all autofillable credentials from the password store and starts
diff --git a/components/password_manager/core/browser/affiliated_match_helper_unittest.cc b/components/password_manager/core/browser/affiliated_match_helper_unittest.cc
index acca937..80e169e3c 100644
--- a/components/password_manager/core/browser/affiliated_match_helper_unittest.cc
+++ b/components/password_manager/core/browser/affiliated_match_helper_unittest.cc
@@ -15,7 +15,7 @@
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
-#include "base/test/test_simple_task_runner.h"
+#include "base/test/scoped_mock_time_message_loop_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/password_manager/core/browser/affiliation_service.h"
 #include "components/password_manager/core/browser/affiliation_utils.h"
@@ -166,37 +166,40 @@
 class AffiliatedMatchHelperTest : public testing::Test {
  public:
   AffiliatedMatchHelperTest()
-      : waiting_task_runner_(new base::TestSimpleTaskRunner),
-        expecting_result_callback_(false),
-        mock_affiliation_service_(nullptr) {}
+      : expecting_result_callback_(false), mock_affiliation_service_(nullptr) {}
   ~AffiliatedMatchHelperTest() override {}
 
  protected:
   void RunDeferredInitialization() {
-    base::TimeDelta expected_init_delay = base::TimeDelta::FromSeconds(
-        AffiliatedMatchHelper::kInitializationDelayOnStartupInSeconds);
-    ASSERT_TRUE(waiting_task_runner()->HasPendingTask());
-    ASSERT_EQ(expected_init_delay,
-              waiting_task_runner()->NextPendingTaskDelay());
-    waiting_task_runner()->RunUntilIdle();
-    base::RunLoop().RunUntilIdle();
+    mock_time_task_runner_->RunUntilIdle();
+    ASSERT_EQ(AffiliatedMatchHelper::kInitializationDelayOnStartup,
+              mock_time_task_runner_->NextPendingTaskDelay());
+    mock_time_task_runner_->FastForwardBy(
+        AffiliatedMatchHelper::kInitializationDelayOnStartup);
+  }
+
+  void RunUntilIdle() {
+    // TODO(gab): Add support for base::RunLoop().RunUntilIdle() in scope of
+    // ScopedMockTimeMessageLoopTaskRunner and use it instead of this helper
+    // method.
+    mock_time_task_runner_->RunUntilIdle();
   }
 
   void AddLogin(const autofill::PasswordForm& form) {
     password_store_->AddLogin(form);
-    base::RunLoop().RunUntilIdle();
+    RunUntilIdle();
   }
 
   void UpdateLoginWithPrimaryKey(
       const autofill::PasswordForm& new_form,
       const autofill::PasswordForm& old_primary_key) {
     password_store_->UpdateLoginWithPrimaryKey(new_form, old_primary_key);
-    base::RunLoop().RunUntilIdle();
+    RunUntilIdle();
   }
 
   void RemoveLogin(const autofill::PasswordForm& form) {
     password_store_->RemoveLogin(form);
-    base::RunLoop().RunUntilIdle();
+    RunUntilIdle();
   }
 
   void AddAndroidAndNonAndroidTestLogins() {
@@ -256,7 +259,7 @@
         observed_form,
         base::Bind(&AffiliatedMatchHelperTest::OnAffiliatedRealmsCallback,
                    base::Unretained(this)));
-    base::RunLoop().RunUntilIdle();
+    RunUntilIdle();
     EXPECT_FALSE(expecting_result_callback_);
     return last_result_realms_;
   }
@@ -268,7 +271,7 @@
         android_form,
         base::Bind(&AffiliatedMatchHelperTest::OnAffiliatedRealmsCallback,
                    base::Unretained(this)));
-    base::RunLoop().RunUntilIdle();
+    RunUntilIdle();
     EXPECT_FALSE(expecting_result_callback_);
     return last_result_realms_;
   }
@@ -281,17 +284,13 @@
         std::move(forms),
         base::Bind(&AffiliatedMatchHelperTest::OnFormsCallback,
                    base::Unretained(this)));
-    base::RunLoop().RunUntilIdle();
+    RunUntilIdle();
     EXPECT_FALSE(expecting_result_callback_);
     return std::move(last_result_forms_);
   }
 
   void DestroyMatchHelper() { match_helper_.reset(); }
 
-  base::TestSimpleTaskRunner* waiting_task_runner() {
-    return waiting_task_runner_.get();
-  }
-
   TestPasswordStore* password_store() { return password_store_.get(); }
 
   MockAffiliationService* mock_affiliation_service() {
@@ -325,7 +324,6 @@
 
     match_helper_.reset(
         new AffiliatedMatchHelper(password_store_.get(), std::move(service)));
-    match_helper_->SetTaskRunnerUsedForWaitingForTesting(waiting_task_runner_);
   }
 
   void TearDown() override {
@@ -334,8 +332,9 @@
     password_store_ = nullptr;
   }
 
-  scoped_refptr<base::TestSimpleTaskRunner> waiting_task_runner_;
   base::MessageLoop message_loop_;
+  base::ScopedMockTimeMessageLoopTaskRunner mock_time_task_runner_;
+
   std::vector<std::string> last_result_realms_;
   std::vector<std::unique_ptr<autofill::PasswordForm>> last_result_forms_;
   bool expecting_result_callback_;
@@ -504,7 +503,7 @@
   AddAndroidAndNonAndroidTestLogins();
 
   match_helper()->Initialize();
-  base::RunLoop().RunUntilIdle();
+  RunUntilIdle();
 
   ExpectPrefetchForAndroidTestLogins();
   ASSERT_NO_FATAL_FAILURE(RunDeferredInitialization());
@@ -516,7 +515,7 @@
 TEST_F(AffiliatedMatchHelperTest,
        PrefetchAffiliationsForAndroidCredentialsAddedInInitializationDelay) {
   match_helper()->Initialize();
-  base::RunLoop().RunUntilIdle();
+  RunUntilIdle();
 
   AddAndroidAndNonAndroidTestLogins();
 
@@ -594,7 +593,7 @@
   AddLogin(android_form2);
 
   match_helper()->Initialize();
-  base::RunLoop().RunUntilIdle();
+  RunUntilIdle();
 
   // Store one credential between initialization and deferred initialization.
   autofill::PasswordForm android_form3(android_form);
@@ -623,7 +622,7 @@
 
 TEST_F(AffiliatedMatchHelperTest, DestroyBeforeDeferredInitialization) {
   match_helper()->Initialize();
-  base::RunLoop().RunUntilIdle();
+  RunUntilIdle();
   DestroyMatchHelper();
   ASSERT_NO_FATAL_FAILURE(RunDeferredInitialization());
 }
diff --git a/components/payments/content/payment_request.cc b/components/payments/content/payment_request.cc
index f7ed68d..e55e68b2 100644
--- a/components/payments/content/payment_request.cc
+++ b/components/payments/content/payment_request.cc
@@ -298,19 +298,19 @@
 
 bool PaymentRequest::ArePaymentOptionsSatisfied() {
   // TODO(mathp): Have a measure of shipping address completeness.
-  if (options_->request_shipping && selected_shipping_profile_ == nullptr)
+  if (request_shipping() && selected_shipping_profile_ == nullptr)
     return false;
 
   // TODO(mathp): Make an encompassing class to validate contact info.
   const std::string& app_locale = delegate_->GetApplicationLocale();
-  if (options_->request_payer_name &&
+  if (request_payer_name() &&
       (selected_contact_profile_ == nullptr ||
        selected_contact_profile_
            ->GetInfo(autofill::AutofillType(autofill::NAME_FULL), app_locale)
            .empty())) {
     return false;
   }
-  if (options_->request_payer_email &&
+  if (request_payer_email() &&
       (selected_contact_profile_ == nullptr ||
        selected_contact_profile_
            ->GetInfo(autofill::AutofillType(autofill::EMAIL_ADDRESS),
@@ -318,7 +318,7 @@
            .empty())) {
     return false;
   }
-  if (options_->request_payer_phone &&
+  if (request_payer_phone() &&
       (selected_contact_profile_ == nullptr ||
        selected_contact_profile_
            ->GetInfo(autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER),
diff --git a/components/payments/content/payment_request.h b/components/payments/content/payment_request.h
index 2a20d68..18d3f94 100644
--- a/components/payments/content/payment_request.h
+++ b/components/payments/content/payment_request.h
@@ -130,6 +130,11 @@
   }
   content::WebContents* web_contents() { return web_contents_; }
 
+  bool request_shipping() const { return options_->request_shipping; }
+  bool request_payer_name() const { return options_->request_payer_name; }
+  bool request_payer_phone() const { return options_->request_payer_phone; }
+  bool request_payer_email() const { return options_->request_payer_email; }
+
   bool is_ready_to_pay() { return is_ready_to_pay_; }
 
  private:
diff --git a/components/subresource_filter/content/browser/async_document_subresource_filter_unittest.cc b/components/subresource_filter/content/browser/async_document_subresource_filter_unittest.cc
index a3cef15..d8c7ea12 100644
--- a/components/subresource_filter/content/browser/async_document_subresource_filter_unittest.cc
+++ b/components/subresource_filter/content/browser/async_document_subresource_filter_unittest.cc
@@ -11,6 +11,8 @@
 #include "base/bind_helpers.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
+#include "base/message_loop/message_loop.h"
+#include "base/run_loop.h"
 #include "base/test/test_simple_task_runner.h"
 #include "base/threading/sequenced_task_runner_handle.h"
 #include "components/subresource_filter/core/common/proto/rules.pb.h"
@@ -22,10 +24,7 @@
 
 class AsyncDocumentSubresourceFilterTest : public ::testing::Test {
  public:
-  AsyncDocumentSubresourceFilterTest()
-      : reply_task_runner_(new base::TestSimpleTaskRunner),
-        reply_task_runner_handle_(reply_task_runner_),
-        blocking_task_runner_(new base::TestSimpleTaskRunner) {}
+  AsyncDocumentSubresourceFilterTest() = default;
 
  protected:
   void SetUp() override {
@@ -52,10 +51,10 @@
   }
 
   void RunUntilIdle() {
-    while (blocking_task_runner_->HasPendingTask() ||
-           reply_task_runner_->HasPendingTask()) {
+    base::RunLoop().RunUntilIdle();
+    while (blocking_task_runner_->HasPendingTask()) {
       blocking_task_runner_->RunUntilIdle();
-      reply_task_runner_->RunUntilIdle();
+      base::RunLoop().RunUntilIdle();
     }
   }
 
@@ -72,9 +71,11 @@
   testing::TestRulesetPair test_ruleset_pair_;
 
   // Note: ADSF assumes a task runner is associated with the current thread.
-  scoped_refptr<base::TestSimpleTaskRunner> reply_task_runner_;
-  base::SequencedTaskRunnerHandle reply_task_runner_handle_;
-  scoped_refptr<base::TestSimpleTaskRunner> blocking_task_runner_;
+  // Instantiate a MessageLoop on the current thread and use RunLoop to handle
+  // the replies ADSF tasks generate.
+  base::MessageLoop message_loop_;
+  scoped_refptr<base::TestSimpleTaskRunner> blocking_task_runner_ =
+      new base::TestSimpleTaskRunner;
 
   std::unique_ptr<VerifiedRulesetDealer::Handle> dealer_handle_;
 
diff --git a/components/suggestions/OWNERS b/components/suggestions/OWNERS
index f5f61960..28c1796 100644
--- a/components/suggestions/OWNERS
+++ b/components/suggestions/OWNERS
@@ -1,2 +1,5 @@
 mathp@chromium.org
 treib@chromium.org
+
+# TEAM: ntp-dev@chromium.org
+# COMPONENT: UI>Browser>NewTabPage
diff --git a/components/sync/driver/sync_stopped_reporter.cc b/components/sync/driver/sync_stopped_reporter.cc
index 7daf57c..5dd869cb 100644
--- a/components/sync/driver/sync_stopped_reporter.cc
+++ b/components/sync/driver/sync_stopped_reporter.cc
@@ -111,9 +111,4 @@
   return sync_service_url.ReplaceComponents(replacements);
 }
 
-void SyncStoppedReporter::SetTimerTaskRunnerForTest(
-    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
-  timer_.SetTaskRunner(task_runner);
-}
-
 }  // namespace syncer
diff --git a/components/sync/driver/sync_stopped_reporter.h b/components/sync/driver/sync_stopped_reporter.h
index 856f87e..af21975 100644
--- a/components/sync/driver/sync_stopped_reporter.h
+++ b/components/sync/driver/sync_stopped_reporter.h
@@ -43,10 +43,6 @@
   // net::URLFetcherDelegate implementation.
   void OnURLFetchComplete(const net::URLFetcher* source) override;
 
-  // Override the timer's task runner so it can be triggered in tests.
-  void SetTimerTaskRunnerForTest(
-      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner);
-
  private:
   // Convert the base sync URL into the sync event URL.
   static GURL GetSyncEventURL(const GURL& sync_service_url);
diff --git a/components/sync/driver/sync_stopped_reporter_unittest.cc b/components/sync/driver/sync_stopped_reporter_unittest.cc
index 70ab87f2..e9d8789 100644
--- a/components/sync/driver/sync_stopped_reporter_unittest.cc
+++ b/components/sync/driver/sync_stopped_reporter_unittest.cc
@@ -6,7 +6,7 @@
 
 #include "base/message_loop/message_loop.h"
 #include "base/run_loop.h"
-#include "base/test/test_simple_task_runner.h"
+#include "base/test/scoped_mock_time_message_loop_task_runner.h"
 #include "base/threading/non_thread_safe.h"
 #include "components/sync/protocol/sync.pb.h"
 #include "net/http/http_status_code.h"
@@ -152,23 +152,18 @@
 }
 
 TEST_F(SyncStoppedReporterTest, Timeout) {
+  // Mock the underlying loop's clock to trigger the timer at will.
+  base::ScopedMockTimeMessageLoopTaskRunner mock_main_runner;
+
   SyncStoppedReporter ssr(test_url(), user_agent(), request_context(),
                           callback());
 
-  // A task runner that can trigger the timeout immediately.
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner(
-      new base::TestSimpleTaskRunner());
-  ssr.SetTimerTaskRunnerForTest(task_runner);
-
   // Begin request.
   ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday);
 
   // Trigger the timeout.
-  ASSERT_TRUE(task_runner->HasPendingTask());
-  task_runner->RunPendingTasks();
-
-  base::RunLoop run_loop;
-  run_loop.RunUntilIdle();
+  ASSERT_TRUE(mock_main_runner->HasPendingTask());
+  mock_main_runner->FastForwardUntilNoTasksRemain();
   EXPECT_EQ(SyncStoppedReporter::RESULT_TIMEOUT, request_result());
 }
 
@@ -183,20 +178,18 @@
 }
 
 TEST_F(SyncStoppedReporterTest, NoCallbackTimeout) {
+  // Mock the underlying loop's clock to trigger the timer at will.
+  base::ScopedMockTimeMessageLoopTaskRunner mock_main_runner;
+
   SyncStoppedReporter ssr(GURL(kTestURL), user_agent(), request_context(),
                           SyncStoppedReporter::ResultCallback());
 
-  // A task runner that can trigger the timeout immediately.
-  scoped_refptr<base::TestSimpleTaskRunner> task_runner(
-      new base::TestSimpleTaskRunner());
-  ssr.SetTimerTaskRunnerForTest(task_runner);
-
   // Begin request.
   ssr.ReportSyncStopped(kAuthToken, kCacheGuid, kBirthday);
 
   // Trigger the timeout.
-  ASSERT_TRUE(task_runner->HasPendingTask());
-  task_runner->RunPendingTasks();
+  ASSERT_TRUE(mock_main_runner->HasPendingTask());
+  mock_main_runner->FastForwardUntilNoTasksRemain();
 }
 
 }  // namespace syncer
diff --git a/components/test/data/autofill/OWNERS b/components/test/data/autofill/OWNERS
index 9d1ddcd..2cb1b739 100644
--- a/components/test/data/autofill/OWNERS
+++ b/components/test/data/autofill/OWNERS
@@ -3,3 +3,5 @@
 
 # Owner for password autofill/generation only.
 gcasto@chromium.org
+
+# COMPONENT: UI>Browser>Autofill
diff --git a/components/ukm/BUILD.gn b/components/ukm/BUILD.gn
index 398d893e..b4c680ab 100644
--- a/components/ukm/BUILD.gn
+++ b/components/ukm/BUILD.gn
@@ -13,6 +13,10 @@
     "metrics_reporting_scheduler.h",
     "persisted_logs_metrics_impl.cc",
     "persisted_logs_metrics_impl.h",
+    "ukm_entry.cc",
+    "ukm_entry.h",
+    "ukm_entry_builder.cc",
+    "ukm_entry_builder.h",
     "ukm_pref_names.cc",
     "ukm_pref_names.h",
     "ukm_service.cc",
diff --git a/components/ukm/ukm_entry.cc b/components/ukm/ukm_entry.cc
new file mode 100644
index 0000000..bdc129b
--- /dev/null
+++ b/components/ukm/ukm_entry.cc
@@ -0,0 +1,32 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/ukm/ukm_entry.h"
+
+#include "base/metrics/metrics_hashes.h"
+#include "components/metrics/proto/ukm/entry.pb.h"
+#include "components/ukm/ukm_source.h"
+
+namespace ukm {
+
+UkmEntry::UkmEntry(int32_t source_id, const char* event_name)
+    : source_id_(source_id), event_hash_(base::HashMetricName(event_name)) {}
+
+UkmEntry::~UkmEntry() {}
+
+void UkmEntry::PopulateProto(Entry* proto_entry) {
+  DCHECK(!proto_entry->has_source_id());
+  DCHECK(!proto_entry->has_event_hash());
+  DCHECK(proto_entry->metrics_size() == 0);
+
+  proto_entry->set_source_id(source_id_);
+  proto_entry->set_event_hash(event_hash_);
+  for (auto& metric : metrics_) {
+    Entry::Metric* proto_metric = proto_entry->add_metrics();
+    proto_metric->set_metric_hash(std::get<0>(metric));
+    proto_metric->set_value(std::get<1>(metric));
+  }
+}
+
+}  // namespace ukm
diff --git a/components/ukm/ukm_entry.h b/components/ukm/ukm_entry.h
new file mode 100644
index 0000000..211c74f4
--- /dev/null
+++ b/components/ukm/ukm_entry.h
@@ -0,0 +1,47 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_UKM_UKM_ENTRY_H_
+#define COMPONENTS_UKM_UKM_ENTRY_H_
+
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+
+namespace ukm {
+
+class Entry;
+class UkmEntryBuilder;
+
+// One UkmEntry contains metrics for a specific source and event. It is
+// connected to a UkmSource by the source ID. The event can be user defined.
+// One example is "PageLoad". Each UkmEntry can have a list of metrics, each of
+// which consist of a metric name and value. When the entry is serialized to the
+// proto message, the event and metric names will be hashed by
+// base::HashMetricName.
+//
+// To build UkmEntry objects, please use UkmEntryBuilder.
+class UkmEntry {
+ public:
+  // Serializes the members of the class into the supplied proto.
+  void PopulateProto(Entry* proto_entry);
+
+  ~UkmEntry();
+
+ private:
+  friend UkmEntryBuilder;
+
+  UkmEntry(int32_t source_id, const char* event_name);
+
+  const int32_t source_id_;
+  const uint64_t event_hash_;
+  std::vector<std::pair<uint64_t, int64_t>> metrics_;
+
+  DISALLOW_COPY_AND_ASSIGN(UkmEntry);
+};
+
+}  // namespace ukm
+
+#endif  // COMPONENTS_UKM_UKM_ENTRY_H_
diff --git a/components/ukm/ukm_entry_builder.cc b/components/ukm/ukm_entry_builder.cc
new file mode 100644
index 0000000..fd64034
--- /dev/null
+++ b/components/ukm/ukm_entry_builder.cc
@@ -0,0 +1,31 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/ukm/ukm_entry_builder.h"
+
+#include "base/metrics/metrics_hashes.h"
+#include "components/ukm/ukm_entry.h"
+#include "components/ukm/ukm_service.h"
+
+namespace ukm {
+
+UkmEntryBuilder::UkmEntryBuilder(const UkmService::AddEntryCallback& callback,
+                                 int32_t source_id,
+                                 const char* event_name)
+    : add_entry_callback_(callback),
+      entry_(new UkmEntry(source_id, event_name)) {}
+
+UkmEntryBuilder::~UkmEntryBuilder() {
+  if (entry_->metrics_.empty())
+    return;
+
+  add_entry_callback_.Run(std::move(entry_));
+}
+
+void UkmEntryBuilder::AddMetric(const char* metric_name, int64_t value) {
+  entry_->metrics_.emplace_back(
+      std::make_pair(base::HashMetricName(metric_name), value));
+}
+
+}  // namespace ukm
diff --git a/components/ukm/ukm_entry_builder.h b/components/ukm/ukm_entry_builder.h
new file mode 100644
index 0000000..e2400ee
--- /dev/null
+++ b/components/ukm/ukm_entry_builder.h
@@ -0,0 +1,54 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_UKM_UKM_ENTRY_BUILDER_H
+#define COMPONENTS_UKM_UKM_ENTRY_BUILDER_H
+
+#include <string>
+
+#include "base/macros.h"
+#include "components/ukm/ukm_service.h"
+
+namespace ukm {
+
+class UkmEntry;
+class UkmService;
+
+// The builder that builds UkmEntry and adds it to UkmService.
+// The example usage is:
+//
+// {
+//   unique_ptr<UkmEntryBuilder> builder =
+//       ukm_service->GetEntryBuilder(source_id, "PageLoad");
+//   builder->AddMetric("NavigationStart", navigation_start_time);
+//   builder->AddMetric("ResponseStart", response_start_time);
+//   builder->AddMetric("FirstPaint", first_paint_time);
+//   builder->AddMetric("FirstContentfulPaint", fcp_time);
+// }
+//
+// When there exists an added metric, the builder will automatically add the
+// UkmEntry to UkmService upon destruction when going out of scope.
+class UkmEntryBuilder {
+ public:
+  // Add metric to the entry. A metric contains a metric name and value.
+  void AddMetric(const char* metric_name, int64_t value);
+
+  ~UkmEntryBuilder();
+
+ private:
+  friend class UkmService;
+
+  UkmEntryBuilder(const UkmService::AddEntryCallback& callback,
+                  int32_t source_id,
+                  const char* event_name);
+
+  UkmService::AddEntryCallback add_entry_callback_;
+  std::unique_ptr<UkmEntry> entry_;
+
+  DISALLOW_COPY_AND_ASSIGN(UkmEntryBuilder);
+};
+
+}  // namespace ukm
+
+#endif  // COMPONENTS_UKM_UKM_ENTRY_BUILDER_H
diff --git a/components/ukm/ukm_service.cc b/components/ukm/ukm_service.cc
index d4816ca..06c3dbb5 100644
--- a/components/ukm/ukm_service.cc
+++ b/components/ukm/ukm_service.cc
@@ -8,6 +8,7 @@
 #include <string>
 #include <utility>
 
+#include "base/bind.h"
 #include "base/feature_list.h"
 #include "base/memory/ptr_util.h"
 #include "base/metrics/field_trial.h"
@@ -18,12 +19,15 @@
 #include "components/metrics/metrics_log.h"
 #include "components/metrics/metrics_log_uploader.h"
 #include "components/metrics/metrics_service_client.h"
+#include "components/metrics/proto/ukm/entry.pb.h"
 #include "components/metrics/proto/ukm/report.pb.h"
 #include "components/metrics/proto/ukm/source.pb.h"
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/pref_service.h"
 #include "components/ukm/metrics_reporting_scheduler.h"
 #include "components/ukm/persisted_logs_metrics_impl.h"
+#include "components/ukm/ukm_entry.h"
+#include "components/ukm/ukm_entry_builder.h"
 #include "components/ukm/ukm_pref_names.h"
 #include "components/ukm/ukm_source.h"
 #include "components/variations/variations_associated_data.h"
@@ -59,7 +63,11 @@
 
 // Maximum number of Sources we'll keep in memory before discarding any
 // new ones being added.
-const size_t kMaxSources = 100;
+const size_t kMaxSources = 500;
+
+// Maximum number of Entries we'll keep in memory before discarding any
+// new ones being added.
+const size_t kMaxEntries = 5000;
 
 std::string GetServerUrl() {
   std::string server_url =
@@ -85,17 +93,23 @@
   return client_id;
 }
 
-enum class DroppedSourceReason {
+enum class DroppedDataReason {
   NOT_DROPPED = 0,
   RECORDING_DISABLED = 1,
-  MAX_SOURCES_HIT = 2,
-  NUM_DROPPED_SOURCES_REASONS
+  MAX_HIT = 2,
+  NUM_DROPPED_DATA_REASONS
 };
 
-void RecordDroppedSource(DroppedSourceReason reason) {
+void RecordDroppedSource(DroppedDataReason reason) {
   UMA_HISTOGRAM_ENUMERATION(
       "UKM.Sources.Dropped", static_cast<int>(reason),
-      static_cast<int>(DroppedSourceReason::NUM_DROPPED_SOURCES_REASONS));
+      static_cast<int>(DroppedDataReason::NUM_DROPPED_DATA_REASONS));
+}
+
+void RecordDroppedEntry(DroppedDataReason reason) {
+  UMA_HISTOGRAM_ENUMERATION(
+      "UKM.Entries.Dropped", static_cast<int>(reason),
+      static_cast<int>(DroppedDataReason::NUM_DROPPED_DATA_REASONS));
 }
 
 }  // namespace
@@ -194,8 +208,10 @@
 void UkmService::Purge() {
   DCHECK(thread_checker_.CalledOnValidThread());
   DVLOG(1) << "UkmService::Purge";
+
   persisted_logs_.Purge();
   sources_.clear();
+  entries_.clear();
 }
 
 void UkmService::ResetClientId() {
@@ -240,8 +256,10 @@
 void UkmService::BuildAndStoreLog() {
   DCHECK(thread_checker_.CalledOnValidThread());
   DVLOG(1) << "UkmService::BuildAndStoreLog";
+
   // Suppress generating a log if we have no new data to include.
-  if (sources_.empty())
+  // TODO(zhenw): add a histogram here to debug if this case is hitting a lot.
+  if (sources_.empty() && entries_.empty())
     return;
 
   Report report;
@@ -251,8 +269,15 @@
     Source* proto_source = report.add_sources();
     source->PopulateProto(proto_source);
   }
+  for (const auto& entry : entries_) {
+    Entry* proto_entry = report.add_entries();
+    entry->PopulateProto(proto_entry);
+  }
+
   UMA_HISTOGRAM_COUNTS_1000("UKM.Sources.SerializedCount", sources_.size());
+  UMA_HISTOGRAM_COUNTS_1000("UKM.Entries.SerializedCount", entries_.size());
   sources_.clear();
+  entries_.clear();
 
   metrics::MetricsLog::RecordCoreSystemProfile(client_,
                                                report.mutable_system_profile());
@@ -328,15 +353,67 @@
   DCHECK(thread_checker_.CalledOnValidThread());
 
   if (!recording_enabled_) {
-    RecordDroppedSource(DroppedSourceReason::RECORDING_DISABLED);
+    RecordDroppedSource(DroppedDataReason::RECORDING_DISABLED);
     return;
   }
   if (sources_.size() >= kMaxSources) {
-    RecordDroppedSource(DroppedSourceReason::MAX_SOURCES_HIT);
+    RecordDroppedSource(DroppedDataReason::MAX_HIT);
     return;
   }
 
   sources_.push_back(std::move(source));
 }
 
+std::unique_ptr<UkmEntryBuilder> UkmService::GetEntryBuilder(
+    int32_t source_id,
+    const char* event_name) {
+  return std::unique_ptr<UkmEntryBuilder>(new UkmEntryBuilder(
+      base::Bind(&UkmService::AddEntry, base::Unretained(this)), source_id,
+      event_name));
+}
+
+void UkmService::UpdateSourceURL(int32_t source_id, const GURL& url) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  if (!recording_enabled_) {
+    RecordDroppedSource(DroppedDataReason::RECORDING_DISABLED);
+    return;
+  }
+
+  // Update the pre-existing source if there is any. This happens when the
+  // initial URL is different from the committed URL for the same source, e.g.,
+  // when there is redirection.
+  for (auto& source : sources_) {
+    if (source_id != source->id())
+      continue;
+
+    source->set_committed_url(url);
+    return;
+  }
+
+  if (sources_.size() >= kMaxSources) {
+    RecordDroppedSource(DroppedDataReason::MAX_HIT);
+    return;
+  }
+  std::unique_ptr<UkmSource> source = base::MakeUnique<UkmSource>();
+  source->set_id(source_id);
+  source->set_committed_url(url);
+  sources_.push_back(std::move(source));
+}
+
+void UkmService::AddEntry(std::unique_ptr<UkmEntry> entry) {
+  DCHECK(thread_checker_.CalledOnValidThread());
+
+  if (!recording_enabled_) {
+    RecordDroppedEntry(DroppedDataReason::RECORDING_DISABLED);
+    return;
+  }
+  if (entries_.size() >= kMaxEntries) {
+    RecordDroppedEntry(DroppedDataReason::MAX_HIT);
+    return;
+  }
+
+  entries_.push_back(std::move(entry));
+}
+
 }  // namespace ukm
diff --git a/components/ukm/ukm_service.h b/components/ukm/ukm_service.h
index 249871f..1775d16a 100644
--- a/components/ukm/ukm_service.h
+++ b/components/ukm/ukm_service.h
@@ -9,6 +9,7 @@
 #include <memory>
 #include <vector>
 
+#include "base/callback.h"
 #include "base/feature_list.h"
 #include "base/macros.h"
 #include "base/memory/weak_ptr.h"
@@ -17,9 +18,11 @@
 #include "components/metrics/metrics_provider.h"
 #include "components/metrics/metrics_reporting_scheduler.h"
 #include "components/metrics/persisted_logs.h"
+#include "url/gurl.h"
 
 class PrefRegistrySimple;
 class PrefService;
+class UkmPageLoadMetricsObserver;
 
 namespace metrics {
 class MetricsLogUploader;
@@ -28,6 +31,8 @@
 
 namespace ukm {
 
+class UkmEntry;
+class UkmEntryBuilder;
 class UkmSource;
 
 // This feature controls whether UkmService should be created.
@@ -44,6 +49,10 @@
   UkmService(PrefService* pref_service, metrics::MetricsServiceClient* client);
   virtual ~UkmService();
 
+  // Update the URL on the source keyed to the given source ID. If the source
+  // does not exist, it will create a new UkmSource object.
+  void UpdateSourceURL(int32_t source_id, const GURL& url);
+
   // Initializes the UKM service.
   void Initialize();
 
@@ -56,10 +65,6 @@
   void EnableReporting();
   void DisableReporting();
 
-  // Adds a new source of UKM metrics, which will be stored
-  // until periodically serialized for upload, and then deleted.
-  void RecordSource(std::unique_ptr<UkmSource> source);
-
   // Records any collected data into logs, and writes to disk.
   void Flush();
 
@@ -78,12 +83,36 @@
   // the provided PrefRegistry.
   static void RegisterPrefs(PrefRegistrySimple* registry);
 
+  using AddEntryCallback = base::Callback<void(std::unique_ptr<UkmEntry>)>;
+
  protected:
   const std::vector<std::unique_ptr<UkmSource>>& sources_for_testing() const {
     return sources_;
   }
 
  private:
+  friend UkmPageLoadMetricsObserver;
+  FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, AddEntryOnlyWithNonEmptyMetrics);
+  FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, EntryBuilderAndSerialization);
+  FRIEND_TEST_ALL_PREFIXES(UkmServiceTest,
+                           LogsUploadedOnlyWhenHavingSourcesOrEntries);
+  FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, MetricsProviderTest);
+  FRIEND_TEST_ALL_PREFIXES(UkmServiceTest, PersistAndPurge);
+
+  // Get a new UkmEntryBuilder object for the specified source ID and event,
+  // which can get metrics added to.
+  //
+  // This API being private is intentional. Any client using UKM needs to
+  // declare itself to be a friend of UkmService and go through code review
+  // process.
+  std::unique_ptr<UkmEntryBuilder> GetEntryBuilder(int32_t source_id,
+                                                   const char* event_name);
+
+  // Adds a new source of UKM metrics, which will be stored until periodically
+  // serialized for upload, and then deleted. This method is deprecated. Please
+  // use GetEntryBuilder and UpdateSourceURL above.
+  void RecordSource(std::unique_ptr<UkmSource> source);
+
   // Starts metrics client initialization.
   void StartInitTask();
 
@@ -104,6 +133,9 @@
   // Called by log_uploader_ when the an upload is completed.
   void OnLogUploadComplete(int response_code);
 
+  // Add an entry to the UkmEntry list.
+  void AddEntry(std::unique_ptr<UkmEntry> entry);
+
   // A weak pointer to the PrefService used to read and write preferences.
   PrefService* pref_service_;
 
@@ -135,9 +167,11 @@
   bool initialize_complete_;
   bool log_upload_in_progress_;
 
-  // Contains newly added sources of UKM metrics which periodically
+  // Contains newly added sources and entries of UKM metrics which periodically
   // get serialized and cleared by BuildAndStoreLog().
+  // TODO(zhenw): update sources to a map keyed by source ID.
   std::vector<std::unique_ptr<UkmSource>> sources_;
+  std::vector<std::unique_ptr<UkmEntry>> entries_;
 
   // Weak pointers factory used to post task on different threads. All weak
   // pointers managed by this factory have the same lifetime as UkmService.
diff --git a/components/ukm/ukm_service_unittest.cc b/components/ukm/ukm_service_unittest.cc
index be8090c..d522606 100644
--- a/components/ukm/ukm_service_unittest.cc
+++ b/components/ukm/ukm_service_unittest.cc
@@ -7,6 +7,8 @@
 #include <string>
 #include <utility>
 
+#include "base/hash.h"
+#include "base/metrics/metrics_hashes.h"
 #include "base/test/test_simple_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "components/metrics/proto/ukm/report.pb.h"
@@ -15,6 +17,7 @@
 #include "components/metrics/test_metrics_service_client.h"
 #include "components/prefs/testing_pref_service.h"
 #include "components/ukm/persisted_logs_metrics_impl.h"
+#include "components/ukm/ukm_entry_builder.h"
 #include "components/ukm/ukm_pref_names.h"
 #include "components/ukm/ukm_source.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -61,14 +64,6 @@
     return report;
   }
 
-  std::unique_ptr<UkmSource> MakeSource(std::string url, int paint_msec) {
-    auto source = base::MakeUnique<UkmSource>();
-    source->set_committed_url(GURL(url));
-    source->set_first_contentful_paint(
-        base::TimeDelta::FromMilliseconds(paint_msec));
-    return source;
-  }
-
  protected:
   TestingPrefServiceSimple prefs_;
   metrics::TestMetricsServiceClient client_;
@@ -104,12 +99,18 @@
   task_runner_->RunUntilIdle();
   service.EnableRecording();
   service.EnableReporting();
-  service.RecordSource(MakeSource("https://google.com", 300));
-  // Should init, generate a log, and start an upload.
+
+  int32_t id = 1;
+  service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+  // Should init, generate a log, and start an upload for source.
   task_runner_->RunPendingTasks();
   EXPECT_TRUE(client_.uploader()->is_uploading());
-  // Flushes the generated log to disk and generates a new one.
-  service.RecordSource(MakeSource("https://google.com", 300));
+  // Flushes the generated log to disk and generates a new entry.
+  {
+    std::unique_ptr<UkmEntryBuilder> builder =
+        service.GetEntryBuilder(id, "PageLoad");
+    builder->AddMetric("FirstContentfulPaint", 300);
+  }
   service.Flush();
   EXPECT_EQ(GetPersistedLogCount(), 2);
   service.Purge();
@@ -124,7 +125,8 @@
   service.EnableRecording();
   service.EnableReporting();
 
-  service.RecordSource(MakeSource("https://google.com", 300));
+  int32_t id = 1;
+  service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
 
   service.Flush();
   EXPECT_EQ(GetPersistedLogCount(), 1);
@@ -133,8 +135,102 @@
   EXPECT_EQ(1, proto_report.sources_size());
   const Source& proto_source = proto_report.sources(0);
 
-  EXPECT_EQ(GURL("https://google.com").spec(), proto_source.url());
-  EXPECT_EQ(300, proto_source.first_contentful_paint_msec());
+  EXPECT_EQ(id, proto_source.id());
+  EXPECT_EQ(GURL("https://google.com/foobar").spec(), proto_source.url());
+}
+
+TEST_F(UkmServiceTest, EntryBuilderAndSerialization) {
+  UkmService service(&prefs_, &client_);
+  EXPECT_EQ(0, GetPersistedLogCount());
+  service.Initialize();
+  task_runner_->RunUntilIdle();
+  service.EnableRecording();
+  service.EnableReporting();
+
+  int32_t id = 1;
+  service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+  {
+    std::unique_ptr<UkmEntryBuilder> foo_builder =
+        service.GetEntryBuilder(id, "foo");
+    foo_builder->AddMetric("foo_start", 0);
+    foo_builder->AddMetric("foo_end", 10);
+
+    std::unique_ptr<UkmEntryBuilder> bar_builder =
+        service.GetEntryBuilder(id, "bar");
+    bar_builder->AddMetric("bar_start", 5);
+    bar_builder->AddMetric("bar_end", 15);
+  }
+
+  service.Flush();
+  EXPECT_EQ(1, GetPersistedLogCount());
+
+  Report proto_report = GetPersistedReport();
+
+  EXPECT_EQ(1, proto_report.sources_size());
+  const Source& proto_source = proto_report.sources(0);
+  EXPECT_EQ(GURL("https://google.com/foobar").spec(), proto_source.url());
+  EXPECT_EQ(id, proto_source.id());
+
+  EXPECT_EQ(2, proto_report.entries_size());
+
+  // Bar entry is the 0th entry here because bar_builder is destructed before
+  // foo_builder: the reverse order as they are constructed. To have the same
+  // ordering as the builders are constructed, one can achieve that by putting
+  // builders in separate scopes.
+  const Entry& proto_entry_bar = proto_report.entries(0);
+  EXPECT_EQ(id, proto_entry_bar.source_id());
+  EXPECT_EQ(base::HashMetricName("bar"), proto_entry_bar.event_hash());
+  EXPECT_EQ(2, proto_entry_bar.metrics_size());
+  const Entry::Metric proto_entry_bar_start = proto_entry_bar.metrics(0);
+  EXPECT_EQ(base::HashMetricName("bar_start"),
+            proto_entry_bar_start.metric_hash());
+  EXPECT_EQ(5, proto_entry_bar_start.value());
+  const Entry::Metric proto_entry_bar_end = proto_entry_bar.metrics(1);
+  EXPECT_EQ(base::HashMetricName("bar_end"), proto_entry_bar_end.metric_hash());
+  EXPECT_EQ(15, proto_entry_bar_end.value());
+
+  const Entry& proto_entry_foo = proto_report.entries(1);
+  EXPECT_EQ(id, proto_entry_foo.source_id());
+  EXPECT_EQ(base::HashMetricName("foo"), proto_entry_foo.event_hash());
+  EXPECT_EQ(2, proto_entry_foo.metrics_size());
+  const Entry::Metric proto_entry_foo_start = proto_entry_foo.metrics(0);
+  EXPECT_EQ(base::HashMetricName("foo_start"),
+            proto_entry_foo_start.metric_hash());
+  EXPECT_EQ(0, proto_entry_foo_start.value());
+  const Entry::Metric proto_entry_foo_end = proto_entry_foo.metrics(1);
+  EXPECT_EQ(base::HashMetricName("foo_end"), proto_entry_foo_end.metric_hash());
+  EXPECT_EQ(10, proto_entry_foo_end.value());
+}
+
+TEST_F(UkmServiceTest, AddEntryOnlyWithNonEmptyMetrics) {
+  UkmService service(&prefs_, &client_);
+  EXPECT_EQ(0, GetPersistedLogCount());
+  service.Initialize();
+  task_runner_->RunUntilIdle();
+  service.EnableRecording();
+  service.EnableReporting();
+
+  int32_t id = 1;
+  service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+
+  {
+    std::unique_ptr<UkmEntryBuilder> builder =
+        service.GetEntryBuilder(id, "PageLoad");
+  }
+  service.Flush();
+  EXPECT_EQ(1, GetPersistedLogCount());
+  Report proto_report = GetPersistedReport();
+  EXPECT_EQ(0, proto_report.entries_size());
+
+  {
+    std::unique_ptr<UkmEntryBuilder> builder =
+        service.GetEntryBuilder(id, "PageLoad");
+    builder->AddMetric("FirstContentfulPaint", 300);
+  }
+  service.Flush();
+  EXPECT_EQ(2, GetPersistedLogCount());
+  Report proto_report_with_entries = GetPersistedReport();
+  EXPECT_EQ(1, proto_report_with_entries.entries_size());
 }
 
 TEST_F(UkmServiceTest, MetricsProviderTest) {
@@ -153,18 +249,25 @@
   service.EnableRecording();
   service.EnableReporting();
 
-  service.RecordSource(MakeSource("https://google.com", 300));
+  int32_t id = 1;
+  service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+  {
+    std::unique_ptr<UkmEntryBuilder> builder =
+        service.GetEntryBuilder(id, "PageLoad");
+    builder->AddMetric("FirstContentfulPaint", 300);
+  }
   service.Flush();
   EXPECT_EQ(GetPersistedLogCount(), 1);
 
   Report proto_report = GetPersistedReport();
   EXPECT_EQ(1, proto_report.sources_size());
+  EXPECT_EQ(1, proto_report.entries_size());
 
   // Providers have now supplied system profile information.
   EXPECT_TRUE(provider->provide_system_profile_metrics_called());
 }
 
-TEST_F(UkmServiceTest, LogsUploadedWithSourcesOnly) {
+TEST_F(UkmServiceTest, LogsUploadedOnlyWhenHavingSourcesOrEntries) {
   UkmService service(&prefs_, &client_);
   EXPECT_EQ(GetPersistedLogCount(), 0);
   service.Initialize();
@@ -178,14 +281,34 @@
   service.Flush();
   EXPECT_EQ(GetPersistedLogCount(), 0);
 
-  service.RecordSource(MakeSource("https://google.com", 300));
+  int32_t id = 1;
+  service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
   // Includes a Source, so will persist.
   service.Flush();
   EXPECT_EQ(GetPersistedLogCount(), 1);
 
+  {
+    std::unique_ptr<UkmEntryBuilder> builder =
+        service.GetEntryBuilder(id, "PageLoad");
+    builder->AddMetric("FirstPaint", 300);
+  }
+  // Includes an Entry, so will persist.
+  service.Flush();
+  EXPECT_EQ(GetPersistedLogCount(), 2);
+
+  service.UpdateSourceURL(id, GURL("https://google.com/foobar"));
+  {
+    std::unique_ptr<UkmEntryBuilder> builder =
+        service.GetEntryBuilder(id, "PageLoad");
+    builder->AddMetric("FirstContentfulPaint", 300);
+  }
+  // Includes a Source and an Entry, so will persist.
+  service.Flush();
+  EXPECT_EQ(GetPersistedLogCount(), 3);
+
   // Current log has no Sources.
   service.Flush();
-  EXPECT_EQ(GetPersistedLogCount(), 1);
+  EXPECT_EQ(GetPersistedLogCount(), 3);
 }
 
 }  // namespace ukm
diff --git a/components/ukm/ukm_source.cc b/components/ukm/ukm_source.cc
index dc2f9e0..d521668 100644
--- a/components/ukm/ukm_source.cc
+++ b/components/ukm/ukm_source.cc
@@ -3,6 +3,8 @@
 // found in the LICENSE file.
 
 #include "components/ukm/ukm_source.h"
+
+#include "base/hash.h"
 #include "components/metrics/proto/ukm/source.pb.h"
 
 namespace ukm {
@@ -12,8 +14,11 @@
 UkmSource::~UkmSource() = default;
 
 void UkmSource::PopulateProto(Source* proto_source) {
-  proto_source->set_url(committed_url_.spec());
+  DCHECK(!proto_source->has_id());
+  DCHECK(!proto_source->has_url());
 
+  proto_source->set_id(id_);
+  proto_source->set_url(committed_url_.spec());
   proto_source->set_first_contentful_paint_msec(
       first_contentful_paint_.InMilliseconds());
 }
diff --git a/components/ukm/ukm_source.h b/components/ukm/ukm_source.h
index 854dd05..d2d99eb 100644
--- a/components/ukm/ukm_source.h
+++ b/components/ukm/ukm_source.h
@@ -6,6 +6,7 @@
 #define COMPONENTS_UKM_UKM_SOURCE_H_
 
 #include <stddef.h>
+#include <map>
 
 #include "base/macros.h"
 #include "base/time/time.h"
@@ -21,6 +22,9 @@
   UkmSource();
   ~UkmSource();
 
+  int32_t id() const { return id_; }
+  void set_id(int32_t id) { id_ = id; }
+
   const GURL& committed_url() const { return committed_url_; }
   void set_committed_url(const GURL& committed_url) {
     committed_url_ = committed_url;
@@ -37,6 +41,7 @@
   void PopulateProto(Source* proto_source);
 
  private:
+  int32_t id_;
   GURL committed_url_;
   base::TimeDelta first_contentful_paint_;
 
diff --git a/components/wallpaper/wallpaper_color_calculator_unittest.cc b/components/wallpaper/wallpaper_color_calculator_unittest.cc
index bc65acf..36e9e6d2 100644
--- a/components/wallpaper/wallpaper_color_calculator_unittest.cc
+++ b/components/wallpaper/wallpaper_color_calculator_unittest.cc
@@ -10,7 +10,7 @@
 #include "base/memory/ptr_util.h"
 #include "base/test/null_task_runner.h"
 #include "base/test/test_mock_time_task_runner.h"
-#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/threading/thread_task_runner_handle.h"
 #include "components/wallpaper/wallpaper_color_calculator_observer.h"
 #include "skia/ext/platform_canvas.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -53,7 +53,8 @@
   ~WallPaperColorCalculatorTest() override;
 
  protected:
-  void InstallTaskRunner(scoped_refptr<base::SequencedTaskRunner> task_runner);
+  void InstallTaskRunner(
+      scoped_refptr<base::SingleThreadTaskRunner> task_runner);
 
   gfx::ImageSkia image_;
 
@@ -65,7 +66,7 @@
 
  private:
   // Required by PostTaskAndReplyImpl.
-  std::unique_ptr<base::SequencedTaskRunnerHandle> task_runner_handle_;
+  std::unique_ptr<base::ThreadTaskRunnerHandle> task_runner_handle_;
 
   DISALLOW_COPY_AND_ASSIGN(WallPaperColorCalculatorTest);
 };
@@ -95,10 +96,10 @@
 WallPaperColorCalculatorTest::~WallPaperColorCalculatorTest() {}
 
 void WallPaperColorCalculatorTest::InstallTaskRunner(
-    scoped_refptr<base::SequencedTaskRunner> task_runner) {
+    scoped_refptr<base::SingleThreadTaskRunner> task_runner) {
   task_runner_handle_.reset();
   task_runner_handle_ =
-      base::MakeUnique<base::SequencedTaskRunnerHandle>(task_runner);
+      base::MakeUnique<base::ThreadTaskRunnerHandle>(task_runner);
   calculator_->SetTaskRunnerForTest(task_runner);
 }
 
diff --git a/content/browser/compositor/gpu_browser_compositor_output_surface.cc b/content/browser/compositor/gpu_browser_compositor_output_surface.cc
index ffe7868ee..4cdfbb7 100644
--- a/content/browser/compositor/gpu_browser_compositor_output_surface.cc
+++ b/content/browser/compositor/gpu_browser_compositor_output_surface.cc
@@ -96,6 +96,8 @@
     const gfx::ColorSpace& color_space,
     bool has_alpha,
     bool use_stencil) {
+  size_ = size;
+  has_set_draw_rectangle_since_last_resize_ = false;
   context_provider()->ContextGL()->ResizeCHROMIUM(
       size.width(), size.height(), device_scale_factor, has_alpha);
 }
@@ -115,6 +117,8 @@
     }
   }
 
+  set_draw_rectangle_for_frame_ = false;
+
   if (frame.sub_buffer_rect) {
     DCHECK(frame.content_bounds.empty());
     context_provider_->ContextSupport()->PartialSwapBuffers(
@@ -148,6 +152,19 @@
     bool suspended) {}
 #endif
 
+void GpuBrowserCompositorOutputSurface::SetDrawRectangle(
+    const gfx::Rect& rect) {
+  if (set_draw_rectangle_for_frame_)
+    return;
+  DCHECK(gfx::Rect(size_).Contains(rect));
+  DCHECK(has_set_draw_rectangle_since_last_resize_ ||
+         (gfx::Rect(size_) == rect));
+  set_draw_rectangle_for_frame_ = true;
+  has_set_draw_rectangle_since_last_resize_ = true;
+  context_provider()->ContextGL()->SetDrawRectangleCHROMIUM(
+      rect.x(), rect.y(), rect.width(), rect.height());
+}
+
 gpu::CommandBufferProxyImpl*
 GpuBrowserCompositorOutputSurface::GetCommandBufferProxy() {
   ui::ContextProviderCommandBuffer* provider_command_buffer =
diff --git a/content/browser/compositor/gpu_browser_compositor_output_surface.h b/content/browser/compositor/gpu_browser_compositor_output_surface.h
index 09fd1ef8..1212ccd0 100644
--- a/content/browser/compositor/gpu_browser_compositor_output_surface.h
+++ b/content/browser/compositor/gpu_browser_compositor_output_surface.h
@@ -76,6 +76,7 @@
   bool IsDisplayedAsOverlayPlane() const override;
   unsigned GetOverlayTextureId() const override;
   bool SurfaceIsSuspendForRecycle() const override;
+  void SetDrawRectangle(const gfx::Rect& rect) override;
 
   // GpuVSyncControl implementation.
   void SetNeedsVSync(bool needs_vsync) override;
@@ -85,6 +86,10 @@
 
   cc::OutputSurfaceClient* client_ = nullptr;
   std::unique_ptr<ReflectorTexture> reflector_texture_;
+  bool set_draw_rectangle_for_frame_ = false;
+  // True if the draw rectangle has been set at all since the last resize.
+  bool has_set_draw_rectangle_since_last_resize_ = false;
+  gfx::Size size_;
   base::WeakPtrFactory<GpuBrowserCompositorOutputSurface> weak_ptr_factory_;
 
  private:
diff --git a/content/browser/compositor/offscreen_browser_compositor_output_surface.cc b/content/browser/compositor/offscreen_browser_compositor_output_surface.cc
index bf2f877..6f13381 100644
--- a/content/browser/compositor/offscreen_browser_compositor_output_surface.cc
+++ b/content/browser/compositor/offscreen_browser_compositor_output_surface.cc
@@ -108,6 +108,11 @@
   }
 }
 
+void OffscreenBrowserCompositorOutputSurface::SetDrawRectangle(
+    const gfx::Rect& draw_rectangle) {
+  NOTREACHED();
+}
+
 void OffscreenBrowserCompositorOutputSurface::Reshape(
     const gfx::Size& size,
     float scale_factor,
diff --git a/content/browser/compositor/offscreen_browser_compositor_output_surface.h b/content/browser/compositor/offscreen_browser_compositor_output_surface.h
index 917b78b3..8c89fd2a 100644
--- a/content/browser/compositor/offscreen_browser_compositor_output_surface.h
+++ b/content/browser/compositor/offscreen_browser_compositor_output_surface.h
@@ -39,6 +39,7 @@
   void BindToClient(cc::OutputSurfaceClient* client) override;
   void EnsureBackbuffer() override;
   void DiscardBackbuffer() override;
+  void SetDrawRectangle(const gfx::Rect& draw_rectangle) override;
   void Reshape(const gfx::Size& size,
                float scale_factor,
                const gfx::ColorSpace& color_space,
diff --git a/content/browser/compositor/reflector_impl_unittest.cc b/content/browser/compositor/reflector_impl_unittest.cc
index 3e41a4b..0a45e1d 100644
--- a/content/browser/compositor/reflector_impl_unittest.cc
+++ b/content/browser/compositor/reflector_impl_unittest.cc
@@ -87,6 +87,7 @@
   void EnsureBackbuffer() override {}
   void DiscardBackbuffer() override {}
   void BindFramebuffer() override {}
+  void SetDrawRectangle(const gfx::Rect& draw_rectangle) override {}
   void Reshape(const gfx::Size& size,
                float device_scale_factor,
                const gfx::ColorSpace& color_space,
diff --git a/content/browser/compositor/software_browser_compositor_output_surface.cc b/content/browser/compositor/software_browser_compositor_output_surface.cc
index 1e5dedd..86d523c 100644
--- a/content/browser/compositor/software_browser_compositor_output_surface.cc
+++ b/content/browser/compositor/software_browser_compositor_output_surface.cc
@@ -54,6 +54,11 @@
   NOTREACHED();
 }
 
+void SoftwareBrowserCompositorOutputSurface::SetDrawRectangle(
+    const gfx::Rect& draw_rectangle) {
+  NOTREACHED();
+}
+
 void SoftwareBrowserCompositorOutputSurface::Reshape(
     const gfx::Size& size,
     float device_scale_factor,
diff --git a/content/browser/compositor/software_browser_compositor_output_surface.h b/content/browser/compositor/software_browser_compositor_output_surface.h
index ee35874..d3bd958a 100644
--- a/content/browser/compositor/software_browser_compositor_output_surface.h
+++ b/content/browser/compositor/software_browser_compositor_output_surface.h
@@ -32,6 +32,7 @@
   void EnsureBackbuffer() override;
   void DiscardBackbuffer() override;
   void BindFramebuffer() override;
+  void SetDrawRectangle(const gfx::Rect& draw_rectangle) override;
   void Reshape(const gfx::Size& size,
                float device_scale_factor,
                const gfx::ColorSpace& color_space,
diff --git a/content/browser/devtools/devtools_frame_trace_recorder.cc b/content/browser/devtools/devtools_frame_trace_recorder.cc
index dc50a054..d0977b7 100644
--- a/content/browser/devtools/devtools_frame_trace_recorder.cc
+++ b/content/browser/devtools/devtools_frame_trace_recorder.cc
@@ -83,7 +83,7 @@
 }
 
 void CaptureFrame(RenderFrameHostImpl* host,
-    const cc::CompositorFrameMetadata& metadata) {
+                  const cc::CompositorFrameMetadata& metadata) {
   RenderWidgetHostViewBase* view =
       static_cast<RenderWidgetHostViewBase*>(host->GetView());
   if (!view)
@@ -92,21 +92,20 @@
   if (current_frame_count >= kMaximumFrameDataCount)
     return;
 
-  gfx::Size src_size = gfx::ToCeiledSize(gfx::ScaleSize(
+  gfx::Size predicted_bitmap_size = gfx::ToCeiledSize(gfx::ScaleSize(
       metadata.scrollable_viewport_size, metadata.page_scale_factor));
   gfx::Size snapshot_size;
-  float area = src_size.GetArea();
+  float area = predicted_bitmap_size.GetArea();
   if (area <= kFrameAreaLimit) {
-    snapshot_size = src_size;
+    snapshot_size = predicted_bitmap_size;
   } else {
     double scale = sqrt(kFrameAreaLimit / area);
-    snapshot_size = gfx::ScaleToCeiledSize(src_size, scale);
+    snapshot_size = gfx::ScaleToCeiledSize(predicted_bitmap_size, scale);
   }
 
-  view->CopyFromCompositingSurface(
-      gfx::Rect(gfx::Point(), src_size), snapshot_size,
-      base::Bind(FrameCaptured, base::TimeTicks::Now()),
-      kN32_SkColorType);
+  view->CopyFromSurface(gfx::Rect(), snapshot_size,
+                        base::Bind(FrameCaptured, base::TimeTicks::Now()),
+                        kN32_SkColorType);
 }
 
 bool ScreenshotCategoryEnabled() {
diff --git a/content/browser/devtools/protocol/color_picker.cc b/content/browser/devtools/protocol/color_picker.cc
index ac04aa4..722df33 100644
--- a/content/browser/devtools/protocol/color_picker.cc
+++ b/content/browser/devtools/protocol/color_picker.cc
@@ -83,11 +83,14 @@
   if (!view)
     return;
 
-  gfx::Size size = view->GetViewBounds().size();
-  view->CopyFromCompositingSurface(
-      gfx::Rect(size), size,
-      base::Bind(&ColorPicker::FrameUpdated,
-                 weak_factory_.GetWeakPtr()),
+  // TODO(miu): This is the wrong size. It's the size of the view on-screen, and
+  // not the rendering size of the view. The latter is what is wanted here, so
+  // that the resulting bitmap's pixel coordinates line-up with the
+  // blink::WebMouseEvent coordinates. http://crbug.com/73362
+  gfx::Size should_be_rendering_size = view->GetViewBounds().size();
+  view->CopyFromSurface(
+      gfx::Rect(), should_be_rendering_size,
+      base::Bind(&ColorPicker::FrameUpdated, weak_factory_.GetWeakPtr()),
       kN32_SkColorType);
 }
 
diff --git a/content/browser/devtools/protocol/color_picker.h b/content/browser/devtools/protocol/color_picker.h
index 6b7afdd..3a443f7 100644
--- a/content/browser/devtools/protocol/color_picker.h
+++ b/content/browser/devtools/protocol/color_picker.h
@@ -7,6 +7,7 @@
 
 #include "base/callback.h"
 #include "base/macros.h"
+#include "content/public/browser/readback_types.h"
 #include "content/public/browser/render_widget_host.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 
diff --git a/content/browser/devtools/protocol/page_handler.cc b/content/browser/devtools/protocol/page_handler.cc
index 12d723b..c31a27ec 100644
--- a/content/browser/devtools/protocol/page_handler.cc
+++ b/content/browser/devtools/protocol/page_handler.cc
@@ -470,6 +470,8 @@
   RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>(
       host_->GetView());
   // TODO(vkuzkokov): do not use previous frame metadata.
+  // TODO(miu): RWHV to provide an API to provide actual rendering size.
+  // http://crbug.com/73362
   cc::CompositorFrameMetadata& metadata = last_compositor_frame_metadata_;
 
   gfx::SizeF viewport_size_dip = gfx::ScaleSize(
@@ -499,9 +501,8 @@
       gfx::ScaleSize(viewport_size_dip, scale)));
 
   if (snapshot_size_dip.width() > 0 && snapshot_size_dip.height() > 0) {
-    gfx::Rect viewport_bounds_dip(gfx::ToRoundedSize(viewport_size_dip));
-    view->CopyFromCompositingSurface(
-        viewport_bounds_dip, snapshot_size_dip,
+    view->CopyFromSurface(
+        gfx::Rect(), snapshot_size_dip,
         base::Bind(&PageHandler::ScreencastFrameCaptured,
                    weak_factory_.GetWeakPtr(),
                    base::Passed(last_compositor_frame_metadata_.Clone())),
diff --git a/content/browser/frame_host/interstitial_page_impl_browsertest.cc b/content/browser/frame_host/interstitial_page_impl_browsertest.cc
index cc2ac14..5d3baee 100644
--- a/content/browser/frame_host/interstitial_page_impl_browsertest.cc
+++ b/content/browser/frame_host/interstitial_page_impl_browsertest.cc
@@ -149,8 +149,9 @@
     // Focus the interstitial frame
     FrameTree* frame_tree = static_cast<RenderViewHostDelegate*>(
                                 interstitial_.get())->GetFrameTree();
-    frame_tree->SetFocusedFrame(frame_tree->root(),
-                                frame_tree->GetMainFrame()->GetSiteInstance());
+    static_cast<RenderFrameHostDelegate*>(interstitial_.get())
+        ->SetFocusedFrame(frame_tree->root(),
+                          frame_tree->GetMainFrame()->GetSiteInstance());
 
     clipboard_message_watcher_ =
         new ClipboardMessageWatcher(interstitial_.get());
diff --git a/content/browser/frame_host/navigation_controller_impl.cc b/content/browser/frame_host/navigation_controller_impl.cc
index bdb0c062..0995603 100644
--- a/content/browser/frame_host/navigation_controller_impl.cc
+++ b/content/browser/frame_host/navigation_controller_impl.cc
@@ -1213,7 +1213,7 @@
     // meanwhile and no new page was created. We are stuck at the last committed
     // entry.
     entry = GetLastCommittedEntry();
-    DCHECK(!is_in_page);
+    CHECK(!is_in_page);
     entry->GetSSL() = handle->ssl_status();
   } else if (params.nav_entry_id) {
     // This is a browser-initiated navigation (back/forward/reload).
diff --git a/content/browser/frame_host/navigation_controller_impl_unittest.cc b/content/browser/frame_host/navigation_controller_impl_unittest.cc
index c8b31922..25030aa 100644
--- a/content/browser/frame_host/navigation_controller_impl_unittest.cc
+++ b/content/browser/frame_host/navigation_controller_impl_unittest.cc
@@ -114,10 +114,6 @@
   }
 
  private:
-  // Overridden from content::NavigationEntryScreenshotManager:
-  void TakeScreenshotImpl(content::RenderViewHost* host,
-                          content::NavigationEntryImpl* entry) override {}
-
   void OnScreenshotSet(content::NavigationEntryImpl* entry) override {
     encoding_screenshot_in_progress_ = false;
     NavigationEntryScreenshotManager::OnScreenshotSet(entry);
diff --git a/content/browser/frame_host/navigation_entry_screenshot_manager.cc b/content/browser/frame_host/navigation_entry_screenshot_manager.cc
index 01f90564..aa740cb 100644
--- a/content/browser/frame_host/navigation_entry_screenshot_manager.cc
+++ b/content/browser/frame_host/navigation_entry_screenshot_manager.cc
@@ -83,6 +83,7 @@
     return;
 
   RenderViewHost* render_view_host = owner_->delegate()->GetRenderViewHost();
+  DCHECK(render_view_host && render_view_host->GetWidget());
   content::RenderWidgetHostView* view =
       render_view_host->GetWidget()->GetView();
   if (!view)
@@ -95,9 +96,18 @@
     return;
   }
 
+  WillTakeScreenshot(render_view_host);
+
   last_screenshot_time_ = now;
 
-  TakeScreenshotImpl(render_view_host, entry);
+  // This screenshot is destined for the UI, so size the result to the actual
+  // on-screen size of the view (and not its device-rendering size).
+  const gfx::Size view_size_on_screen = view->GetViewBounds().size();
+  view->CopyFromSurface(
+      gfx::Rect(), view_size_on_screen,
+      base::Bind(&NavigationEntryScreenshotManager::OnScreenshotTaken,
+                 screenshot_factory_.GetWeakPtr(), entry->GetUniqueID()),
+      kAlpha_8_SkColorType);
 }
 
 // Implemented here and not in NavigationEntry because this manager keeps track
@@ -110,18 +120,6 @@
   DCHECK_EQ(GetScreenshotCount(), 0);
 }
 
-void NavigationEntryScreenshotManager::TakeScreenshotImpl(
-    RenderViewHost* host,
-    NavigationEntryImpl* entry) {
-  DCHECK(host && host->GetWidget()->GetView());
-  DCHECK(entry);
-  host->GetWidget()->CopyFromBackingStore(
-      gfx::Rect(), host->GetWidget()->GetView()->GetViewBounds().size(),
-      base::Bind(&NavigationEntryScreenshotManager::OnScreenshotTaken,
-                 screenshot_factory_.GetWeakPtr(), entry->GetUniqueID()),
-      kAlpha_8_SkColorType);
-}
-
 void NavigationEntryScreenshotManager::SetMinScreenshotIntervalMS(
     int interval_ms) {
   DCHECK_GE(interval_ms, 0);
diff --git a/content/browser/frame_host/navigation_entry_screenshot_manager.h b/content/browser/frame_host/navigation_entry_screenshot_manager.h
index 40600af..508b189 100644
--- a/content/browser/frame_host/navigation_entry_screenshot_manager.h
+++ b/content/browser/frame_host/navigation_entry_screenshot_manager.h
@@ -38,8 +38,10 @@
   void ClearAllScreenshots();
 
  protected:
-  virtual void TakeScreenshotImpl(RenderViewHost* host,
-                                  NavigationEntryImpl* entry);
+  // Overridden by tests to be notified when a screenshot will be taken. Tests
+  // can override OnScreenshotSet() to be notified after the screenshot is
+  // taken.
+  virtual void WillTakeScreenshot(RenderViewHost* host) {}
 
   // Called after a screenshot has been set on an NavigationEntryImpl.
   // Overridden in tests to get notified of when a screenshot is set.
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 47e3577c..fb68c4c3 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
@@ -581,8 +581,8 @@
   frame_swapped_callbacks_.push_back(std::move(callback));
 }
 
-void RenderWidgetHostViewChildFrame::CopyFromCompositingSurface(
-    const gfx::Rect& src_subrect,
+void RenderWidgetHostViewChildFrame::CopyFromSurface(
+    const gfx::Rect& src_rect,
     const gfx::Size& output_size,
     const ReadbackRequestCallback& callback,
     const SkColorType preferred_color_type) {
@@ -591,11 +591,11 @@
     // point we should be guaranteed that the surface is available.
     RegisterFrameSwappedCallback(base::MakeUnique<base::Closure>(base::Bind(
         &RenderWidgetHostViewChildFrame::SubmitSurfaceCopyRequest, AsWeakPtr(),
-        src_subrect, output_size, callback, preferred_color_type)));
+        src_rect, output_size, callback, preferred_color_type)));
     return;
   }
 
-  SubmitSurfaceCopyRequest(src_subrect, output_size, callback,
+  SubmitSurfaceCopyRequest(src_rect, output_size, callback,
                            preferred_color_type);
 }
 
@@ -617,18 +617,6 @@
   support_->RequestCopyOfSurface(std::move(request));
 }
 
-void RenderWidgetHostViewChildFrame::CopyFromCompositingSurfaceToVideoFrame(
-    const gfx::Rect& src_subrect,
-    const scoped_refptr<media::VideoFrame>& target,
-    const base::Callback<void(const gfx::Rect&, bool)>& callback) {
-  NOTIMPLEMENTED();
-  callback.Run(gfx::Rect(), false);
-}
-
-bool RenderWidgetHostViewChildFrame::CanCopyToVideoFrame() const {
-  return false;
-}
-
 bool RenderWidgetHostViewChildFrame::HasAcceleratedSurface(
       const gfx::Size& desired_size) {
   return false;
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 3bf35d1b..87e2de41 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
@@ -76,6 +76,10 @@
   void Focus() override;
   bool HasFocus() const override;
   bool IsSurfaceAvailableForCopy() const override;
+  void CopyFromSurface(const gfx::Rect& src_rect,
+                       const gfx::Size& output_size,
+                       const ReadbackRequestCallback& callback,
+                       const SkColorType color_type) override;
   void Show() override;
   void Hide() override;
   bool IsShowing() override;
@@ -99,16 +103,6 @@
                          int error_code) override;
   void Destroy() override;
   void SetTooltipText(const base::string16& tooltip_text) override;
-  void CopyFromCompositingSurface(
-      const gfx::Rect& src_subrect,
-      const gfx::Size& dst_size,
-      const ReadbackRequestCallback& callback,
-      const SkColorType preferred_color_type) override;
-  void CopyFromCompositingSurfaceToVideoFrame(
-      const gfx::Rect& src_subrect,
-      const scoped_refptr<media::VideoFrame>& target,
-      const base::Callback<void(const gfx::Rect&, bool)>& callback) override;
-  bool CanCopyToVideoFrame() const override;
   bool HasAcceleratedSurface(const gfx::Size& desired_size) override;
   void GestureEventAck(const blink::WebGestureEvent& event,
                        InputEventAckState ack_result) override;
diff --git a/content/browser/media/capture/web_contents_video_capture_device.cc b/content/browser/media/capture/web_contents_video_capture_device.cc
index 336ec0ee..146f310 100644
--- a/content/browser/media/capture/web_contents_video_capture_device.cc
+++ b/content/browser/media/capture/web_contents_video_capture_device.cc
@@ -196,7 +196,7 @@
   // Computes the preferred size of the target RenderWidget for optimal capture.
   gfx::Size ComputeOptimalViewSize() const;
 
-  // Response callback for RWHVP::CopyFromCompositingSurfaceToVideoFrame().
+  // Response callback for RWHV::CopyFromSurfaceToVideoFrame().
   void DidCopyToVideoFrame(
       const base::TimeTicks& start_time,
       const RenderWidgetHostViewFrameSubscriber::DeliverFrameCallback&
@@ -545,16 +545,11 @@
         deliver_frame_cb) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  auto* const view =
-      static_cast<RenderWidgetHostViewBase*>(tracker_->GetTargetView());
-  if (!view || !view->CanCopyToVideoFrame()) {
-    deliver_frame_cb.Run(base::TimeTicks(), gfx::Rect(), false);
+  RenderWidgetHostView* const view = tracker_->GetTargetView();
+  if (!view)
     return;
-  }
-
-  const gfx::Size view_size = view->GetViewBounds().size();
-  view->CopyFromCompositingSurfaceToVideoFrame(
-      gfx::Rect(view_size), std::move(target),
+  view->CopyFromSurfaceToVideoFrame(
+      gfx::Rect(), std::move(target),
       base::Bind(&WebContentsCaptureMachine::DidCopyToVideoFrame,
                  weak_ptr_factory_.GetWeakPtr(), start_time, deliver_frame_cb));
 }
@@ -632,7 +627,8 @@
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
   // Capture can fail due to transient issues, so just skip this frame.
-  DVLOG_IF(1, !success) << "CopyFromCompositingSurface failed; skipping frame.";
+  DVLOG_IF(1, !success)
+      << "CopyFromSurfaceToVideoFrame() failed; skipping frame.";
   deliver_frame_cb.Run(start_time, region_in_frame, success);
 }
 
diff --git a/content/browser/media/capture/web_contents_video_capture_device.h b/content/browser/media/capture/web_contents_video_capture_device.h
index 0446175..29ca8f3 100644
--- a/content/browser/media/capture/web_contents_video_capture_device.h
+++ b/content/browser/media/capture/web_contents_video_capture_device.h
@@ -22,8 +22,7 @@
 // content::RenderWidgetHostView implementation that supports frame subscription
 // (via BeginFrameSubscription()), and can perform read-back into
 // media::VideoFrames (i.e.,
-// RenderWidgetHostViewBase::CopyFromCompositingSurfaceToVideoFrame() is
-// functional).
+// RenderWidgetHostViewBase::CopyFromSurfaceToVideoFrame() is functional).
 //
 // An instance is created by providing a device_id.  The device_id contains
 // information necessary for finding a WebContents instance.  From then on,
diff --git a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
index 1c1f656..d86758c 100644
--- a/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
+++ b/content/browser/media/capture/web_contents_video_capture_device_unittest.cc
@@ -99,9 +99,9 @@
 }
 
 // A stub implementation which fills solid-colors into VideoFrames in calls to
-// CopyFromCompositingSurfaceToVideoFrame(). The colors are changed by tests
-// in-between draw events to confirm that the right frames have the right
-// content and in the right sequence.
+// CopyFromSurfaceToVideoFrame(). The colors are changed by tests in-between
+// draw events to confirm that the right frames have the right content and in
+// the right sequence.
 class CaptureTestView : public TestRenderWidgetHostView {
  public:
   explicit CaptureTestView(RenderWidgetHostImpl* rwh)
@@ -124,12 +124,21 @@
     fake_bounds_ = rect;
   }
 
-  bool CanCopyToVideoFrame() const override { return true; }
+  bool IsSurfaceAvailableForCopy() const override { return true; }
 
-  void CopyFromCompositingSurfaceToVideoFrame(
+  void CopyFromSurface(const gfx::Rect& src_rect,
+                       const gfx::Size& output_size,
+                       const ReadbackRequestCallback& callback,
+                       const SkColorType color_type) override {
+    // WebContentsVideoCaptureDevice implementation does not use this.
+    NOTREACHED();
+  }
+
+  void CopyFromSurfaceToVideoFrame(
       const gfx::Rect& src_subrect,
-      const scoped_refptr<media::VideoFrame>& target,
+      scoped_refptr<media::VideoFrame> target,
       const base::Callback<void(const gfx::Rect&, bool)>& callback) override {
+    ASSERT_TRUE(src_subrect.IsEmpty());
     media::FillYUV(target.get(), SkColorGetR(yuv_color_),
                    SkColorGetG(yuv_color_), SkColorGetB(yuv_color_));
     BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
@@ -155,8 +164,8 @@
     scoped_refptr<media::VideoFrame> target;
     if (subscriber_ && subscriber_->ShouldCaptureFrame(
             gfx::Rect(), present_time, &target, &callback)) {
-      CopyFromCompositingSurfaceToVideoFrame(
-          gfx::Rect(), target, base::Bind(callback, present_time));
+      CopyFromSurfaceToVideoFrame(gfx::Rect(), target,
+                                  base::Bind(callback, present_time));
     }
   }
 
@@ -451,11 +460,11 @@
     // TODO(nick): Sadness and woe! Much "mock-the-world" boilerplate could be
     // eliminated here, if only we could use RenderViewHostTestHarness. The
     // catch is that we need to inject our CaptureTestView::
-    // CopyFromCompositingSurfaceToVideoFrame() mock. To accomplish that,
-    // either RenderViewHostTestHarness would have to support installing a
-    // custom RenderViewHostFactory, or else we implant some kind of delegated
-    // CopyFromCompositingSurfaceToVideoFrame functionality into
-    // TestRenderViewHostView itself.
+    // CopyFromSurfaceToVideoFrame() mock. To accomplish that, either
+    // RenderViewHostTestHarness would have to support installing a custom
+    // RenderViewHostFactory, or else we implant some kind of delegated
+    // CopyFromSurfaceToVideoFrame functionality into TestRenderWidgetHostView
+    // itself.
 
     render_process_host_factory_.reset(new MockRenderProcessHostFactory());
     // Create our (self-registering) RVH factory, so that when we create a
diff --git a/content/browser/renderer_host/browser_compositor_view_mac.h b/content/browser/renderer_host/browser_compositor_view_mac.h
index 51589ba..d0ecb715 100644
--- a/content/browser/renderer_host/browser_compositor_view_mac.h
+++ b/content/browser/renderer_host/browser_compositor_view_mac.h
@@ -90,7 +90,7 @@
                                   SkColorType preferred_color_type);
   void CopyFromCompositingSurfaceToVideoFrame(
       const gfx::Rect& src_subrect,
-      const scoped_refptr<media::VideoFrame>& target,
+      scoped_refptr<media::VideoFrame> target,
       const base::Callback<void(const gfx::Rect&, bool)>& callback);
 
   // Indicate that the recyclable compositor should be destroyed, and no future
diff --git a/content/browser/renderer_host/browser_compositor_view_mac.mm b/content/browser/renderer_host/browser_compositor_view_mac.mm
index 3e3776b..e4c25e73 100644
--- a/content/browser/renderer_host/browser_compositor_view_mac.mm
+++ b/content/browser/renderer_host/browser_compositor_view_mac.mm
@@ -14,6 +14,7 @@
 #include "content/browser/renderer_host/resize_lock.h"
 #include "content/public/browser/browser_thread.h"
 #include "content/public/browser/context_factory.h"
+#include "media/base/video_frame.h"
 #include "ui/accelerated_widget_mac/accelerated_widget_mac.h"
 #include "ui/accelerated_widget_mac/window_resize_helper_mac.h"
 #include "ui/base/layout.h"
@@ -253,7 +254,7 @@
 
 void BrowserCompositorMac::CopyFromCompositingSurfaceToVideoFrame(
     const gfx::Rect& src_subrect,
-    const scoped_refptr<media::VideoFrame>& target,
+    scoped_refptr<media::VideoFrame> target,
     const base::Callback<void(const gfx::Rect&, bool)>& callback) {
   DCHECK(delegated_frame_host_);
   DCHECK(state_ == HasAttachedCompositor);
@@ -264,7 +265,7 @@
                  weak_factory_.GetWeakPtr(), callback);
 
   delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame(
-      src_subrect, target, callback_with_decrement);
+      src_subrect, std::move(target), callback_with_decrement);
 }
 
 void BrowserCompositorMac::SwapCompositorFrame(
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index da2cc35..073ffc5 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -229,6 +229,8 @@
     context_provider()->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0);
   }
 
+  void SetDrawRectangle(const gfx::Rect& rect) override {}
+
   void Reshape(const gfx::Size& size,
                float device_scale_factor,
                const gfx::ColorSpace& color_space,
diff --git a/content/browser/renderer_host/delegated_frame_host.cc b/content/browser/renderer_host/delegated_frame_host.cc
index d2c861f..bec9b52 100644
--- a/content/browser/renderer_host/delegated_frame_host.cc
+++ b/content/browser/renderer_host/delegated_frame_host.cc
@@ -136,7 +136,7 @@
                          (preferred_color_type == kRGB_565_SkColorType) ||
                          (preferred_color_type == kN32_SkColorType));
   DCHECK(format_support);
-  if (!CanCopyToBitmap()) {
+  if (!CanCopyFromCompositingSurface()) {
     callback.Run(SkBitmap(), content::READBACK_SURFACE_UNAVAILABLE);
     return;
   }
@@ -152,9 +152,9 @@
 
 void DelegatedFrameHost::CopyFromCompositingSurfaceToVideoFrame(
     const gfx::Rect& src_subrect,
-    const scoped_refptr<media::VideoFrame>& target,
+    scoped_refptr<media::VideoFrame> target,
     const base::Callback<void(const gfx::Rect&, bool)>& callback) {
-  if (!CanCopyToVideoFrame()) {
+  if (!CanCopyFromCompositingSurface()) {
     callback.Run(gfx::Rect(), false);
     return;
   }
@@ -163,17 +163,13 @@
       cc::CopyOutputRequest::CreateRequest(base::Bind(
           &DelegatedFrameHost::CopyFromCompositingSurfaceHasResultForVideo,
           AsWeakPtr(),  // For caching the ReadbackYUVInterface on this class.
-          nullptr, target, callback));
-  request->set_area(src_subrect);
+          nullptr, std::move(target), callback));
+  if (!src_subrect.IsEmpty())
+    request->set_area(src_subrect);
   RequestCopyOfOutput(std::move(request));
 }
 
-bool DelegatedFrameHost::CanCopyToBitmap() const {
-  return compositor_ &&
-         client_->DelegatedFrameHostGetLayer()->has_external_content();
-}
-
-bool DelegatedFrameHost::CanCopyToVideoFrame() const {
+bool DelegatedFrameHost::CanCopyFromCompositingSurface() const {
   return compositor_ &&
          client_->DelegatedFrameHostGetLayer()->has_external_content();
 }
@@ -297,7 +293,6 @@
     bottom_gutter_->SetBounds(
         gfx::Rect(0, current_frame_size_in_dip_.height(), width, height));
     client_->DelegatedFrameHostGetLayer()->Add(bottom_gutter_.get());
-
   } else {
     bottom_gutter_.reset();
   }
@@ -323,7 +318,7 @@
 
 void DelegatedFrameHost::AttemptFrameSubscriberCapture(
     const gfx::Rect& damage_rect) {
-  if (!frame_subscriber() || !CanCopyToVideoFrame())
+  if (!frame_subscriber() || !CanCopyFromCompositingSurface())
     return;
 
   const base::TimeTicks now = tick_clock_->NowTicks();
@@ -369,16 +364,12 @@
         subscriber_texture->target()));
   }
 
-  if (local_surface_id_.is_valid()) {
-    // To avoid unnecessary composites, go directly to the Surface rather than
-    // through RequestCopyOfOutput (which goes through the browser
-    // compositor).
-    if (!request_copy_of_output_callback_for_testing_.is_null())
-      request_copy_of_output_callback_for_testing_.Run(std::move(request));
-    else
-      support_->RequestCopyOfSurface(std::move(request));
+  // To avoid unnecessary browser composites, try to go directly to the Surface
+  // rather than through the Layer (which goes through the browser compositor).
+  if (local_surface_id_.is_valid() &&
+      request_copy_of_output_callback_for_testing_.is_null()) {
+    support_->RequestCopyOfSurface(std::move(request));
   } else {
-    request->set_area(gfx::Rect(current_frame_size_in_dip_));
     RequestCopyOfOutput(std::move(request));
   }
 }
@@ -457,18 +448,10 @@
       allocated_new_local_surface_id = true;
     }
 
-    gfx::Size desired_size = client_->DelegatedFrameHostDesiredSizeInDIP();
-    if (desired_size != frame_size_in_dip && !desired_size.IsEmpty()) {
-      skipped_latency_info_list_.insert(skipped_latency_info_list_.end(),
-                                        frame.metadata.latency_info.begin(),
-                                        frame.metadata.latency_info.end());
-      frame.metadata.latency_info.clear();
-    } else {
-      frame.metadata.latency_info.insert(frame.metadata.latency_info.end(),
-                                         skipped_latency_info_list_.begin(),
-                                         skipped_latency_info_list_.end());
-      skipped_latency_info_list_.clear();
-    }
+    frame.metadata.latency_info.insert(frame.metadata.latency_info.end(),
+                                       skipped_latency_info_list_.begin(),
+                                       skipped_latency_info_list_.end());
+    skipped_latency_info_list_.clear();
 
     support_->SubmitCompositorFrame(local_surface_id_, std::move(frame));
 
@@ -682,6 +665,10 @@
             ? display_compositor::GLHelper::SCALER_QUALITY_BEST
             : display_compositor::GLHelper::SCALER_QUALITY_FAST;
 
+    DVLOG(1) << "Re-creating YUV readback pipeline for source rect "
+             << result_rect.ToString() << " and destination size "
+             << region_in_frame.size().ToString();
+
     dfh->yuv_readback_pipeline_.reset(gl_helper->CreateReadbackPipelineYUV(
         quality, result_rect.size(), result_rect, region_in_frame.size(), true,
         true));
@@ -822,11 +809,16 @@
 
 void DelegatedFrameHost::RequestCopyOfOutput(
     std::unique_ptr<cc::CopyOutputRequest> request) {
-  if (!request_copy_of_output_callback_for_testing_.is_null()) {
-    request_copy_of_output_callback_for_testing_.Run(std::move(request));
-  } else {
+  // If a specific area has not been requested, set one to ensure correct
+  // clipping occurs.
+  if (!request->has_area())
+    request->set_area(gfx::Rect(current_frame_size_in_dip_));
+
+  if (request_copy_of_output_callback_for_testing_.is_null()) {
     client_->DelegatedFrameHostGetLayer()->RequestCopyOfOutput(
         std::move(request));
+  } else {
+    request_copy_of_output_callback_for_testing_.Run(std::move(request));
   }
 }
 
diff --git a/content/browser/renderer_host/delegated_frame_host.h b/content/browser/renderer_host/delegated_frame_host.h
index c650d71..01f4f65 100644
--- a/content/browser/renderer_host/delegated_frame_host.h
+++ b/content/browser/renderer_host/delegated_frame_host.h
@@ -121,8 +121,6 @@
   void WillDrawSurface(const cc::LocalSurfaceId& id,
                        const gfx::Rect& damage_rect) override;
 
-  bool CanCopyToBitmap() const;
-
   // Public interface exposed to RenderWidgetHostView.
 
   void SwapDelegatedFrame(uint32_t compositor_frame_sink_id,
@@ -135,17 +133,18 @@
   gfx::Size GetRequestedRendererSize() const;
   void SetCompositor(ui::Compositor* compositor);
   void ResetCompositor();
-  // Note: |src_subset| is specified in DIP dimensions while |output_size|
-  // expects pixels.
+  // Note: |src_subrect| is specified in DIP dimensions while |output_size|
+  // expects pixels. If |src_subrect| is empty, the entire surface area is
+  // copied.
   void CopyFromCompositingSurface(const gfx::Rect& src_subrect,
                                   const gfx::Size& output_size,
                                   const ReadbackRequestCallback& callback,
                                   const SkColorType preferred_color_type);
   void CopyFromCompositingSurfaceToVideoFrame(
       const gfx::Rect& src_subrect,
-      const scoped_refptr<media::VideoFrame>& target,
+      scoped_refptr<media::VideoFrame> target,
       const base::Callback<void(const gfx::Rect&, bool)>& callback);
-  bool CanCopyToVideoFrame() const;
+  bool CanCopyFromCompositingSurface() const;
   void BeginFrameSubscription(
       std::unique_ptr<RenderWidgetHostViewFrameSubscriber> subscriber);
   void EndFrameSubscription();
diff --git a/content/browser/renderer_host/p2p/OWNERS b/content/browser/renderer_host/p2p/OWNERS
index 5e2b3d6..70573c4 100644
--- a/content/browser/renderer_host/p2p/OWNERS
+++ b/content/browser/renderer_host/p2p/OWNERS
@@ -1,2 +1,4 @@
 sergeyu@chromium.org
 juberti@chromium.org
+
+# COMPONENT: Blink>WebRTC
diff --git a/content/browser/renderer_host/render_widget_helper.h b/content/browser/renderer_host/render_widget_helper.h
index c88ac17e..3e46e2c1 100644
--- a/content/browser/renderer_host/render_widget_helper.h
+++ b/content/browser/renderer_host/render_widget_helper.h
@@ -29,36 +29,6 @@
 // behalf of a RenderWidgetHost.  This class bridges between the IO thread
 // where the RenderProcessHost's MessageFilter lives and the UI thread where
 // the RenderWidgetHost lives.
-//
-//
-// OPTIMIZED TAB SWITCHING
-//
-//   When a RenderWidgetHost is in a background tab, it is flagged as hidden.
-//   This causes the corresponding RenderWidget to stop sending BackingStore
-//   messages. The RenderWidgetHost also discards its backingstore when it is
-//   hidden, which helps free up memory.  As a result, when a RenderWidgetHost
-//   is restored, it can be momentarily be without a backingstore.  (Restoring
-//   a RenderWidgetHost results in a WasShown message being sent to the
-//   RenderWidget, which triggers a full BackingStore message.)  This can lead
-//   to an observed rendering glitch as the WebContentsImpl will just have to
-//   fill white overtop the RenderWidgetHost until the RenderWidgetHost
-//   receives a BackingStore message to refresh its backingstore.
-//
-//   To avoid this 'white flash', the RenderWidgetHost again makes use of the
-//   RenderWidgetHelper's WaitForBackingStoreMsg method.  When the
-//   RenderWidgetHost's GetBackingStore method is called, it will call
-//   WaitForBackingStoreMsg if it has no backingstore.
-//
-// TRANSPORT DIB CREATION
-//
-//   On some platforms (currently the Mac) the renderer cannot create transport
-//   DIBs because of sandbox limitations. Thus, it has to make synchronous IPCs
-//   to the browser for them. Since these requests are synchronous, they cannot
-//   terminate on the UI thread. Thus, in this case, this object performs the
-//   allocation and maintains the set of allocated transport DIBs which the
-//   renderers can refer to.
-//
-
 class RenderWidgetHelper
     : public base::RefCountedThreadSafe<RenderWidgetHelper,
                                         BrowserThread::DeleteOnIOThread> {
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 0f488d8..15b8995 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -831,31 +831,6 @@
   SetView(NULL);
 }
 
-void RenderWidgetHostImpl::CopyFromBackingStore(
-    const gfx::Rect& src_subrect,
-    const gfx::Size& accelerated_dst_size,
-    const ReadbackRequestCallback& callback,
-    const SkColorType preferred_color_type) {
-  if (view_) {
-    TRACE_EVENT0("browser",
-        "RenderWidgetHostImpl::CopyFromBackingStore::FromCompositingSurface");
-    gfx::Rect accelerated_copy_rect = src_subrect.IsEmpty() ?
-        gfx::Rect(view_->GetViewBounds().size()) : src_subrect;
-    view_->CopyFromCompositingSurface(accelerated_copy_rect,
-                                      accelerated_dst_size, callback,
-                                      preferred_color_type);
-    return;
-  }
-
-  callback.Run(SkBitmap(), content::READBACK_FAILED);
-}
-
-bool RenderWidgetHostImpl::CanCopyFromBackingStore() {
-  if (view_)
-    return view_->IsSurfaceAvailableForCopy();
-  return false;
-}
-
 #if defined(OS_MACOSX)
 void RenderWidgetHostImpl::PauseForPendingResizeOrRepaints() {
   TRACE_EVENT0("browser",
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 8d83000..b6aa99ec 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -38,7 +38,6 @@
 #include "content/common/input/input_event_ack_state.h"
 #include "content/common/input/synthetic_gesture_packet.h"
 #include "content/common/view_message_enums.h"
-#include "content/public/browser/readback_types.h"
 #include "content/public/browser/render_widget_host.h"
 #include "content/public/common/page_zoom.h"
 #include "content/public/common/url_constants.h"
@@ -144,11 +143,6 @@
   void Focus() override;
   void Blur() override;
   void SetActive(bool active) override;
-  void CopyFromBackingStore(const gfx::Rect& src_rect,
-                            const gfx::Size& accelerated_dst_size,
-                            const ReadbackRequestCallback& callback,
-                            const SkColorType preferred_color_type) override;
-  bool CanCopyFromBackingStore() override;
   void ForwardMouseEvent(const blink::WebMouseEvent& mouse_event) override;
   void ForwardWheelEvent(const blink::WebMouseWheelEvent& wheel_event) override;
   void ForwardKeyboardEvent(const NativeWebKeyboardEvent& key_event) override;
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 5b47fbad..33a8673 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -550,8 +550,7 @@
       gfx::ScaleToCeiledSize(src_subrect.size(), scale / device_scale_factor));
   src_subrect = gfx::ConvertRectToDIP(device_scale_factor, src_subrect);
 
-  CopyFromCompositingSurface(src_subrect, dst_size, result_callback,
-                             preferred_color_type);
+  CopyFromSurface(src_subrect, dst_size, result_callback, preferred_color_type);
 }
 
 bool RenderWidgetHostViewAndroid::HasValidFrame() const {
@@ -919,12 +918,12 @@
   UpdateBackgroundColor(color);
 }
 
-void RenderWidgetHostViewAndroid::CopyFromCompositingSurface(
+void RenderWidgetHostViewAndroid::CopyFromSurface(
     const gfx::Rect& src_subrect,
     const gfx::Size& dst_size,
     const ReadbackRequestCallback& callback,
     const SkColorType preferred_color_type) {
-  TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::CopyFromCompositingSurface");
+  TRACE_EVENT0("cc", "RenderWidgetHostViewAndroid::CopyFromSurface");
   if (!host_ || !IsSurfaceAvailableForCopy()) {
     callback.Run(SkBitmap(), READBACK_SURFACE_UNAVAILABLE);
     return;
@@ -964,18 +963,6 @@
                  preferred_color_type, start_time, callback, readback_lock));
 }
 
-void RenderWidgetHostViewAndroid::CopyFromCompositingSurfaceToVideoFrame(
-    const gfx::Rect& src_subrect,
-    const scoped_refptr<media::VideoFrame>& target,
-    const base::Callback<void(const gfx::Rect&, bool)>& callback) {
-  NOTIMPLEMENTED();
-  callback.Run(gfx::Rect(), false);
-}
-
-bool RenderWidgetHostViewAndroid::CanCopyToVideoFrame() const {
-  return false;
-}
-
 void RenderWidgetHostViewAndroid::ShowDisambiguationPopup(
     const gfx::Rect& rect_pixels, const SkBitmap& zoomed_bitmap) {
   if (!content_view_core_)
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 dc3c6e705..8df14f6e 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -92,13 +92,17 @@
   gfx::NativeViewAccessible GetNativeViewAccessible() override;
   void Focus() override;
   bool HasFocus() const override;
-  bool IsSurfaceAvailableForCopy() const override;
   void Show() override;
   void Hide() override;
   bool IsShowing() override;
   gfx::Rect GetViewBounds() const override;
   gfx::Size GetVisibleViewportSize() const override;
   gfx::Size GetPhysicalBackingSize() const override;
+  bool IsSurfaceAvailableForCopy() const override;
+  void CopyFromSurface(const gfx::Rect& src_rect,
+                       const gfx::Size& output_size,
+                       const ReadbackRequestCallback& callback,
+                       const SkColorType color_type) override;
   bool DoBrowserControlsShrinkBlinkSize() const override;
   float GetTopControlsHeight() const override;
   float GetBottomControlsHeight() const override;
@@ -112,16 +116,6 @@
   void SetTooltipText(const base::string16& tooltip_text) override;
   bool HasAcceleratedSurface(const gfx::Size& desired_size) override;
   void SetBackgroundColor(SkColor color) override;
-  void CopyFromCompositingSurface(
-      const gfx::Rect& src_subrect,
-      const gfx::Size& dst_size,
-      const ReadbackRequestCallback& callback,
-      const SkColorType preferred_color_type) override;
-  void CopyFromCompositingSurfaceToVideoFrame(
-      const gfx::Rect& src_subrect,
-      const scoped_refptr<media::VideoFrame>& target,
-      const base::Callback<void(const gfx::Rect&, bool)>& callback) override;
-  bool CanCopyToVideoFrame() const override;
   gfx::Rect GetBoundsInRootWindow() override;
   void ProcessAckedTouchEvent(const TouchEventWithLatencyInfo& touch,
                               InputEventAckState ack_result) override;
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index 010e059..6dcfa00 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -58,6 +58,7 @@
 #include "content/public/common/child_process_host.h"
 #include "content/public/common/content_switches.h"
 #include "gpu/ipc/common/gpu_messages.h"
+#include "media/base/video_frame.h"
 #include "services/service_manager/public/cpp/interface_provider.h"
 #include "services/ui/public/interfaces/window_manager_constants.mojom.h"
 #include "third_party/WebKit/public/platform/WebInputEvent.h"
@@ -737,8 +738,9 @@
 }
 
 bool RenderWidgetHostViewAura::IsSurfaceAvailableForCopy() const {
-  return delegated_frame_host_ ? delegated_frame_host_->CanCopyToBitmap()
-                               : false;
+  if (!delegated_frame_host_)
+    return false;
+  return delegated_frame_host_->CanCopyFromCompositingSurface();
 }
 
 bool RenderWidgetHostViewAura::IsShowing() {
@@ -850,30 +852,29 @@
              : RenderWidgetHostViewBase::GetRequestedRendererSize();
 }
 
-void RenderWidgetHostViewAura::CopyFromCompositingSurface(
+void RenderWidgetHostViewAura::CopyFromSurface(
     const gfx::Rect& src_subrect,
     const gfx::Size& dst_size,
     const ReadbackRequestCallback& callback,
     const SkColorType preferred_color_type) {
-  if (!delegated_frame_host_)
+  if (!IsSurfaceAvailableForCopy()) {
+    callback.Run(SkBitmap(), READBACK_SURFACE_UNAVAILABLE);
     return;
+  }
   delegated_frame_host_->CopyFromCompositingSurface(
       src_subrect, dst_size, callback, preferred_color_type);
 }
 
-void RenderWidgetHostViewAura::CopyFromCompositingSurfaceToVideoFrame(
+void RenderWidgetHostViewAura::CopyFromSurfaceToVideoFrame(
     const gfx::Rect& src_subrect,
-    const scoped_refptr<media::VideoFrame>& target,
+    scoped_refptr<media::VideoFrame> target,
     const base::Callback<void(const gfx::Rect&, bool)>& callback) {
-  if (!delegated_frame_host_)
+  if (!IsSurfaceAvailableForCopy()) {
+    callback.Run(gfx::Rect(), false);
     return;
+  }
   delegated_frame_host_->CopyFromCompositingSurfaceToVideoFrame(
-      src_subrect, target, callback);
-}
-
-bool RenderWidgetHostViewAura::CanCopyToVideoFrame() const {
-  return delegated_frame_host_ ? delegated_frame_host_->CanCopyToVideoFrame()
-                               : false;
+      src_subrect, std::move(target), callback);
 }
 
 void RenderWidgetHostViewAura::BeginFrameSubscription(
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index dabb048..f889d1f 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -109,7 +109,6 @@
   gfx::NativeViewAccessible GetNativeViewAccessible() override;
   ui::TextInputClient* GetTextInputClient() override;
   bool HasFocus() const override;
-  bool IsSurfaceAvailableForCopy() const override;
   void Show() override;
   void Hide() override;
   bool IsShowing() override;
@@ -134,16 +133,15 @@
   void Destroy() override;
   void SetTooltipText(const base::string16& tooltip_text) override;
   gfx::Size GetRequestedRendererSize() const override;
-  void CopyFromCompositingSurface(
-      const gfx::Rect& src_subrect,
-      const gfx::Size& dst_size,
-      const ReadbackRequestCallback& callback,
-      const SkColorType preferred_color_type) override;
-  void CopyFromCompositingSurfaceToVideoFrame(
-      const gfx::Rect& src_subrect,
-      const scoped_refptr<media::VideoFrame>& target,
+  bool IsSurfaceAvailableForCopy() const override;
+  void CopyFromSurface(const gfx::Rect& src_rect,
+                       const gfx::Size& output_size,
+                       const ReadbackRequestCallback& callback,
+                       const SkColorType color_type) override;
+  void CopyFromSurfaceToVideoFrame(
+      const gfx::Rect& src_rect,
+      scoped_refptr<media::VideoFrame> target,
       const base::Callback<void(const gfx::Rect&, bool)>& callback) override;
-  bool CanCopyToVideoFrame() const override;
   void BeginFrameSubscription(
       std::unique_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) override;
   void EndFrameSubscription() override;
diff --git a/content/browser/renderer_host/render_widget_host_view_base.cc b/content/browser/renderer_host/render_widget_host_view_base.cc
index d09da07..901613f3 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.cc
+++ b/content/browser/renderer_host/render_widget_host_view_base.cc
@@ -16,6 +16,7 @@
 #include "content/browser/renderer_host/render_widget_host_view_frame_subscriber.h"
 #include "content/browser/renderer_host/text_input_manager.h"
 #include "content/common/content_switches_internal.h"
+#include "media/base/video_frame.h"
 #include "ui/display/display.h"
 #include "ui/display/screen.h"
 #include "ui/gfx/geometry/point_conversions.h"
@@ -156,6 +157,27 @@
   return false;
 }
 
+bool RenderWidgetHostViewBase::IsSurfaceAvailableForCopy() const {
+  return false;
+}
+
+void RenderWidgetHostViewBase::CopyFromSurface(
+    const gfx::Rect& src_rect,
+    const gfx::Size& output_size,
+    const ReadbackRequestCallback& callback,
+    const SkColorType color_type) {
+  NOTIMPLEMENTED();
+  callback.Run(SkBitmap(), READBACK_SURFACE_UNAVAILABLE);
+}
+
+void RenderWidgetHostViewBase::CopyFromSurfaceToVideoFrame(
+    const gfx::Rect& src_rect,
+    scoped_refptr<media::VideoFrame> target,
+    const base::Callback<void(const gfx::Rect&, bool)>& callback) {
+  NOTIMPLEMENTED();
+  callback.Run(gfx::Rect(), false);
+}
+
 bool RenderWidgetHostViewBase::IsShowingContextMenu() const {
   return showing_context_menu_;
 }
diff --git a/content/browser/renderer_host/render_widget_host_view_base.h b/content/browser/renderer_host/render_widget_host_view_base.h
index b7e0cda7..657ad202 100644
--- a/content/browser/renderer_host/render_widget_host_view_base.h
+++ b/content/browser/renderer_host/render_widget_host_view_base.h
@@ -24,7 +24,6 @@
 #include "content/browser/renderer_host/event_with_latency_info.h"
 #include "content/common/content_export.h"
 #include "content/common/input/input_event_ack_state.h"
-#include "content/public/browser/readback_types.h"
 #include "content/public/browser/render_widget_host_view.h"
 #include "content/public/common/screen_info.h"
 #include "ipc/ipc_listener.h"
@@ -102,6 +101,15 @@
   bool IsMouseLocked() override;
   gfx::Size GetVisibleViewportSize() const override;
   void SetInsets(const gfx::Insets& insets) override;
+  bool IsSurfaceAvailableForCopy() const override;
+  void CopyFromSurface(const gfx::Rect& src_rect,
+                       const gfx::Size& output_size,
+                       const ReadbackRequestCallback& callback,
+                       const SkColorType color_type) override;
+  void CopyFromSurfaceToVideoFrame(
+      const gfx::Rect& src_rect,
+      scoped_refptr<media::VideoFrame> target,
+      const base::Callback<void(const gfx::Rect&, bool)>& callback) override;
   void BeginFrameSubscription(
       std::unique_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) override;
   void EndFrameSubscription() override;
@@ -347,43 +355,6 @@
   // the page has changed.
   virtual void SetTooltipText(const base::string16& tooltip_text) = 0;
 
-  // Copies the contents of the compositing surface, providing a new SkBitmap
-  // result via an asynchronously-run |callback|. |src_subrect| is specified in
-  // layer space coordinates for the current platform (e.g., DIP for Aura/Mac,
-  // physical for Android), and is the region to be copied from this view. When
-  // |src_subrect| is empty then the whole surface will be copied. The copy is
-  // then scaled to a SkBitmap of size |dst_size|. If |dst_size| is empty then
-  // output will be unscaled. |callback| is run with true on success,
-  // false otherwise. A smaller region than |src_subrect| may be copied
-  // if the underlying surface is smaller than |src_subrect|.
-  virtual void CopyFromCompositingSurface(
-      const gfx::Rect& src_subrect,
-      const gfx::Size& dst_size,
-      const ReadbackRequestCallback& callback,
-      const SkColorType preferred_color_type) = 0;
-
-  // Copies the contents of the compositing surface, populating the given
-  // |target| with YV12 image data. |src_subrect| is specified in layer space
-  // coordinates for the current platform (e.g., DIP for Aura/Mac, physical for
-  // Android), and is the region to be copied from this view. The copy is then
-  // scaled and letterboxed with black borders to fit |target|. Finally,
-  // |callback| is asynchronously run with true/false for
-  // success/failure. |target| must point to an allocated, YV12 video frame of
-  // the intended size. This operation will fail if there is no available
-  // compositing surface.
-  virtual void CopyFromCompositingSurfaceToVideoFrame(
-      const gfx::Rect& src_subrect,
-      const scoped_refptr<media::VideoFrame>& target,
-      const base::Callback<void(const gfx::Rect&, bool)>& callback) = 0;
-
-  // Returns true if CopyFromCompositingSurfaceToVideoFrame() is likely to
-  // succeed.
-  //
-  // TODO(nick): When VideoFrame copies are broadly implemented, this method
-  // should be renamed to HasCompositingSurface(), or unified with
-  // IsSurfaceAvailableForCopy() and HasAcceleratedSurface().
-  virtual bool CanCopyToVideoFrame() const = 0;
-
   // Return true if the view has an accelerated surface that contains the last
   // presented frame for the view. If |desired_size| is non-empty, true is
   // returned only if the accelerated surface size matches.
diff --git a/content/browser/renderer_host/render_widget_host_view_browsertest.cc b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
index c67e49f49..bd8f4c9 100644
--- a/content/browser/renderer_host/render_widget_host_view_browsertest.cc
+++ b/content/browser/renderer_host/render_widget_host_view_browsertest.cc
@@ -111,10 +111,10 @@
         GetRenderViewHost()->GetWidget()->GetView());
   }
 
-  // Callback when using CopyFromBackingStore() API.
-  void FinishCopyFromBackingStore(const base::Closure& quit_closure,
-                                  const SkBitmap& bitmap,
-                                  ReadbackResponse response) {
+  // Callback when using CopyFromSurface() API.
+  void FinishCopyFromSurface(const base::Closure& quit_closure,
+                             const SkBitmap& bitmap,
+                             ReadbackResponse response) {
     ++callback_invoke_count_;
     if (response == READBACK_SUCCESS) {
       ++frames_captured_;
@@ -124,10 +124,10 @@
       quit_closure.Run();
   }
 
-  // Callback when using CopyFromCompositingSurfaceToVideoFrame() API.
-  void FinishCopyFromCompositingSurface(const base::Closure& quit_closure,
-                                        const gfx::Rect& region_in_frame,
-                                        bool frame_captured) {
+  // Callback when using CopyFromSurfaceToVideoFrame() API.
+  void FinishCopyFromSurfaceToVideoFrame(const base::Closure& quit_closure,
+                                         const gfx::Rect& region_in_frame,
+                                         bool frame_captured) {
     ++callback_invoke_count_;
     if (frame_captured)
       ++frames_captured_;
@@ -149,8 +149,8 @@
       task_runner->PostTask(FROM_HERE, quit_closure);
   }
 
-  // Copy one frame using the CopyFromBackingStore API.
-  void RunBasicCopyFromBackingStoreTest() {
+  // Copy one frame using the CopyFromSurface API.
+  void RunBasicCopyFromSurfaceTest() {
     SET_UP_SURFACE_OR_PASS_TEST(NULL);
 
     // Repeatedly call CopyFromBackingStore() since, on some platforms (e.g.,
@@ -160,11 +160,10 @@
     while (true) {
       ++count_attempts;
       base::RunLoop run_loop;
-      GetRenderViewHost()->GetWidget()->CopyFromBackingStore(
+      GetRenderWidgetHostView()->CopyFromSurface(
           gfx::Rect(), frame_size(),
-          base::Bind(
-              &RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
-              base::Unretained(this), run_loop.QuitClosure()),
+          base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromSurface,
+                     base::Unretained(this), run_loop.QuitClosure()),
           kN32_SkColorType);
       run_loop.Run();
 
@@ -283,23 +282,23 @@
 // Disable tests for Android as it has an incomplete implementation.
 #if !defined(OS_ANDROID)
 
-// The CopyFromBackingStore() API should work on all platforms when compositing
-// is enabled.
+// The CopyFromSurface() API should work on all platforms when compositing is
+// enabled.
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
-                       CopyFromBackingStore) {
-  RunBasicCopyFromBackingStoreTest();
+                       CopyFromSurface) {
+  RunBasicCopyFromSurfaceTest();
 }
 
-// Tests that the callback passed to CopyFromBackingStore is always called,
-// even when the RenderWidgetHost is deleting in the middle of an async copy.
+// Tests that the callback passed to CopyFromSurface is always called, even
+// when the RenderWidgetHostView is deleting in the middle of an async copy.
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
-                       CopyFromBackingStore_CallbackDespiteDelete) {
+                       CopyFromSurface_CallbackDespiteDelete) {
   SET_UP_SURFACE_OR_PASS_TEST(NULL);
 
   base::RunLoop run_loop;
-  GetRenderViewHost()->GetWidget()->CopyFromBackingStore(
+  GetRenderWidgetHostView()->CopyFromSurface(
       gfx::Rect(), frame_size(),
-      base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromBackingStore,
+      base::Bind(&RenderWidgetHostViewBrowserTest::FinishCopyFromSurface,
                  base::Unretained(this), run_loop.QuitClosure()),
       kN32_SkColorType);
   run_loop.Run();
@@ -307,26 +306,20 @@
   EXPECT_EQ(1, callback_invoke_count());
 }
 
-// Tests that the callback passed to CopyFromCompositingSurfaceToVideoFrame is
-// always called, even when the RenderWidgetHost is deleting in the middle of
-// an async copy.
+// Tests that the callback passed to CopyFromSurfaceToVideoFrame is always
+// called, even when the RenderWidgetHostView is deleting in the middle of an
+// async copy.
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest,
-                       CopyFromCompositingSurface_CallbackDespiteDelete) {
+                       CopyFromSurfaceToVideoFrame_CallbackDespiteDelete) {
   SET_UP_SURFACE_OR_PASS_TEST(NULL);
-  RenderWidgetHostViewBase* const view = GetRenderWidgetHostView();
-  if (!view->CanCopyToVideoFrame()) {
-    LOG(WARNING) <<
-        ("Blindly passing this test: CopyFromCompositingSurfaceToVideoFrame() "
-         "not supported on this platform.");
-    return;
-  }
 
   base::RunLoop run_loop;
   scoped_refptr<media::VideoFrame> dest =
       media::VideoFrame::CreateBlackFrame(frame_size());
-  view->CopyFromCompositingSurfaceToVideoFrame(
-      gfx::Rect(view->GetViewBounds().size()), dest, base::Bind(
-          &RenderWidgetHostViewBrowserTest::FinishCopyFromCompositingSurface,
+  GetRenderWidgetHostView()->CopyFromSurfaceToVideoFrame(
+      gfx::Rect(), dest,
+      base::Bind(
+          &RenderWidgetHostViewBrowserTest::FinishCopyFromSurfaceToVideoFrame,
           base::Unretained(this), run_loop.QuitClosure()));
   run_loop.Run();
 
@@ -357,12 +350,6 @@
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTest, CopyTwice) {
   SET_UP_SURFACE_OR_PASS_TEST(NULL);
   RenderWidgetHostViewBase* const view = GetRenderWidgetHostView();
-  if (!view->CanCopyToVideoFrame()) {
-    LOG(WARNING) << ("Blindly passing this test: "
-                     "CopyFromCompositingSurfaceToVideoFrame() not supported "
-                     "on this platform.");
-    return;
-  }
 
   base::RunLoop run_loop;
   scoped_refptr<media::VideoFrame> first_output =
@@ -372,13 +359,13 @@
       media::VideoFrame::CreateBlackFrame(frame_size());
   ASSERT_TRUE(second_output.get());
   base::Closure closure = base::BarrierClosure(2, run_loop.QuitClosure());
-  view->CopyFromCompositingSurfaceToVideoFrame(
-      gfx::Rect(view->GetViewBounds().size()), first_output,
+  view->CopyFromSurfaceToVideoFrame(
+      gfx::Rect(), first_output,
       base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
                  base::Unretained(this), base::ThreadTaskRunnerHandle::Get(),
                  closure, base::TimeTicks::Now()));
-  view->CopyFromCompositingSurfaceToVideoFrame(
-      gfx::Rect(view->GetViewBounds().size()), second_output,
+  view->CopyFromSurfaceToVideoFrame(
+      gfx::Rect(), second_output,
       base::Bind(&RenderWidgetHostViewBrowserTest::FrameDelivered,
                  base::Unretained(this), base::ThreadTaskRunnerHandle::Get(),
                  closure, base::TimeTicks::Now()));
@@ -570,7 +557,6 @@
       return;
 
     RenderWidgetHostViewBase* rwhv = GetRenderWidgetHostView();
-    ASSERT_TRUE(!video_frame || rwhv->CanCopyToVideoFrame());
 
     SetupLeftRightBitmap(output_size,
                          &expected_copy_from_compositing_surface_bitmap_);
@@ -617,8 +603,7 @@
                            ReadbackRequestCallbackForVideo,
                        base::Unretained(this), video_frame,
                        run_loop.QuitClosure());
-        rwhv->CopyFromCompositingSurfaceToVideoFrame(
-            copy_rect, video_frame, callback);
+        rwhv->CopyFromSurfaceToVideoFrame(copy_rect, video_frame, callback);
       } else {
         if (!content::GpuDataManager::GetInstance()
                  ->CanUseGpuBrowserCompositor()) {
@@ -634,8 +619,8 @@
                            ReadbackRequestCallbackTest,
                        base::Unretained(this),
                        run_loop.QuitClosure());
-        rwhv->CopyFromCompositingSurface(
-            copy_rect, output_size, callback, kN32_SkColorType);
+        rwhv->CopyFromSurface(copy_rect, output_size, callback,
+                              kN32_SkColorType);
       }
       run_loop.Run();
 
@@ -705,7 +690,7 @@
 };
 
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
-                       CopyFromCompositingSurface_Origin_Unscaled) {
+                       CopyFromSurface_Origin_Unscaled) {
   gfx::Rect copy_rect(400, 300);
   gfx::Size output_size = copy_rect.size();
   gfx::Size html_rect_size(400, 300);
@@ -717,7 +702,7 @@
 }
 
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
-                       CopyFromCompositingSurface_Origin_Scaled) {
+                       CopyFromSurface_Origin_Scaled) {
   gfx::Rect copy_rect(400, 300);
   gfx::Size output_size(200, 100);
   gfx::Size html_rect_size(400, 300);
@@ -729,7 +714,7 @@
 }
 
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
-                       CopyFromCompositingSurface_Cropped_Unscaled) {
+                       CopyFromSurface_Cropped_Unscaled) {
   // Grab 60x60 pixels from the center of the tab contents.
   gfx::Rect copy_rect(400, 300);
   copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(30, 30),
@@ -744,7 +729,7 @@
 }
 
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
-                       CopyFromCompositingSurface_Cropped_Scaled) {
+                       CopyFromSurface_Cropped_Scaled) {
   // Grab 60x60 pixels from the center of the tab contents.
   gfx::Rect copy_rect(400, 300);
   copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(30, 30),
@@ -759,7 +744,7 @@
 }
 
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
-                       CopyFromCompositingSurface_ForVideoFrame) {
+                       CopyFromSurface_ForVideoFrame) {
   // Grab 90x60 pixels from the center of the tab contents.
   gfx::Rect copy_rect(400, 300);
   copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(45, 30),
@@ -774,7 +759,7 @@
 }
 
 IN_PROC_BROWSER_TEST_P(CompositingRenderWidgetHostViewBrowserTestTabCapture,
-                       CopyFromCompositingSurface_ForVideoFrame_Scaled) {
+                       CopyFromSurface_ForVideoFrame_Scaled) {
   // Grab 90x60 pixels from the center of the tab contents.
   gfx::Rect copy_rect(400, 300);
   copy_rect = gfx::Rect(copy_rect.CenterPoint() - gfx::Vector2d(45, 30),
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.h b/content/browser/renderer_host/render_widget_host_view_mac.h
index 3395188..3cde2482 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.h
+++ b/content/browser/renderer_host/render_widget_host_view_mac.h
@@ -262,7 +262,6 @@
   gfx::NativeView GetNativeView() const override;
   gfx::NativeViewAccessible GetNativeViewAccessible() override;
   bool HasFocus() const override;
-  bool IsSurfaceAvailableForCopy() const override;
   void Show() override;
   void Hide() override;
   bool IsShowing() override;
@@ -290,15 +289,15 @@
                          int error_code) override;
   void Destroy() override;
   void SetTooltipText(const base::string16& tooltip_text) override;
-  void CopyFromCompositingSurface(const gfx::Rect& src_subrect,
-                                  const gfx::Size& dst_size,
-                                  const ReadbackRequestCallback& callback,
-                                  SkColorType preferred_color_type) override;
-  void CopyFromCompositingSurfaceToVideoFrame(
-      const gfx::Rect& src_subrect,
-      const scoped_refptr<media::VideoFrame>& target,
+  bool IsSurfaceAvailableForCopy() const override;
+  void CopyFromSurface(const gfx::Rect& src_rect,
+                       const gfx::Size& output_size,
+                       const ReadbackRequestCallback& callback,
+                       const SkColorType color_type) override;
+  void CopyFromSurfaceToVideoFrame(
+      const gfx::Rect& src_rect,
+      scoped_refptr<media::VideoFrame> target,
       const base::Callback<void(const gfx::Rect&, bool)>& callback) override;
-  bool CanCopyToVideoFrame() const override;
   void BeginFrameSubscription(
       std::unique_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) override;
   void EndFrameSubscription() override;
diff --git a/content/browser/renderer_host/render_widget_host_view_mac.mm b/content/browser/renderer_host/render_widget_host_view_mac.mm
index 3609b89..f39fef18 100644
--- a/content/browser/renderer_host/render_widget_host_view_mac.mm
+++ b/content/browser/renderer_host/render_widget_host_view_mac.mm
@@ -19,9 +19,9 @@
 #include "base/debug/crash_logging.h"
 #include "base/logging.h"
 #include "base/mac/scoped_cftyperef.h"
+#import "base/mac/scoped_nsobject.h"
 #include "base/mac/sdk_forward_declarations.h"
 #include "base/macros.h"
-#import "base/mac/scoped_nsobject.h"
 #include "base/memory/ref_counted.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/numerics/safe_conversions.h"
@@ -65,6 +65,7 @@
 #import "content/public/browser/render_widget_host_view_mac_delegate.h"
 #include "content/public/browser/web_contents.h"
 #include "gpu/ipc/common/gpu_messages.h"
+#include "media/base/video_frame.h"
 #include "skia/ext/platform_canvas.h"
 #include "skia/ext/skia_utils_mac.h"
 #include "third_party/WebKit/public/platform/WebInputEvent.h"
@@ -861,7 +862,8 @@
 }
 
 bool RenderWidgetHostViewMac::IsSurfaceAvailableForCopy() const {
-  return browser_compositor_->GetDelegatedFrameHost()->CanCopyToBitmap();
+  return browser_compositor_->GetDelegatedFrameHost()
+      ->CanCopyFromCompositingSurface();
 }
 
 bool RenderWidgetHostViewMac::IsShowing() {
@@ -1174,7 +1176,7 @@
   return popup_type_ != blink::WebPopupTypeNone;
 }
 
-void RenderWidgetHostViewMac::CopyFromCompositingSurface(
+void RenderWidgetHostViewMac::CopyFromSurface(
     const gfx::Rect& src_subrect,
     const gfx::Size& dst_size,
     const ReadbackRequestCallback& callback,
@@ -1183,16 +1185,12 @@
       src_subrect, dst_size, callback, preferred_color_type);
 }
 
-void RenderWidgetHostViewMac::CopyFromCompositingSurfaceToVideoFrame(
+void RenderWidgetHostViewMac::CopyFromSurfaceToVideoFrame(
     const gfx::Rect& src_subrect,
-    const scoped_refptr<media::VideoFrame>& target,
+    scoped_refptr<media::VideoFrame> target,
     const base::Callback<void(const gfx::Rect&, bool)>& callback) {
-  browser_compositor_->CopyFromCompositingSurfaceToVideoFrame(src_subrect,
-                                                              target, callback);
-}
-
-bool RenderWidgetHostViewMac::CanCopyToVideoFrame() const {
-  return browser_compositor_->GetDelegatedFrameHost()->CanCopyToVideoFrame();
+  browser_compositor_->CopyFromCompositingSurfaceToVideoFrame(
+      src_subrect, std::move(target), callback);
 }
 
 void RenderWidgetHostViewMac::BeginFrameSubscription(
diff --git a/content/browser/web_contents/web_contents_view_aura_browsertest.cc b/content/browser/web_contents/web_contents_view_aura_browsertest.cc
index ea91142..c88996d 100644
--- a/content/browser/web_contents/web_contents_view_aura_browsertest.cc
+++ b/content/browser/web_contents/web_contents_view_aura_browsertest.cc
@@ -136,11 +136,9 @@
 
  private:
   // Overridden from NavigationEntryScreenshotManager:
-  void TakeScreenshotImpl(RenderViewHost* host,
-                          NavigationEntryImpl* entry) override {
+  void WillTakeScreenshot(RenderViewHost* host) override {
     ++waiting_for_screenshots_;
     screenshot_taken_for_ = host;
-    NavigationEntryScreenshotManager::TakeScreenshotImpl(host, entry);
   }
 
   void OnScreenshotSet(NavigationEntryImpl* entry) override {
diff --git a/content/public/browser/render_widget_host.h b/content/public/browser/render_widget_host.h
index 48336e4..068e826 100644
--- a/content/public/browser/render_widget_host.h
+++ b/content/public/browser/render_widget_host.h
@@ -10,7 +10,6 @@
 #include "base/callback.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/native_web_keyboard_event.h"
-#include "content/public/browser/readback_types.h"
 #include "content/public/common/drop_data.h"
 #include "ipc/ipc_channel.h"
 #include "ipc/ipc_sender.h"
@@ -18,14 +17,9 @@
 #include "third_party/WebKit/public/platform/WebGestureEvent.h"
 #include "third_party/WebKit/public/platform/WebInputEvent.h"
 #include "third_party/WebKit/public/web/WebTextDirection.h"
-#include "third_party/skia/include/core/SkImageInfo.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/surface/transport_dib.h"
 
-namespace gfx {
-class Rect;
-}
-
 namespace blink {
 class WebMouseEvent;
 class WebMouseWheelEvent;
@@ -163,27 +157,6 @@
   // contents, but e.g. in the omnibox.
   virtual void SetActive(bool active) = 0;
 
-  // Copies the given subset of the backing store, and passes the result as a
-  // bitmap to a callback.
-  //
-  // If |src_rect| is empty, the whole contents is copied. If non empty
-  // |accelerated_dst_size| is given and accelerated compositing is active, the
-  // content is shrunk so that it fits in |accelerated_dst_size|. If
-  // |accelerated_dst_size| is larger than the content size, the content is not
-  // resized. If |accelerated_dst_size| is empty, the size copied from the
-  // source contents is used. |callback| is invoked with true on success, false
-  // otherwise, along with a SkBitmap containing the copied pixel data.
-  //
-  // NOTE: |callback| is called synchronously if the backing store is available.
-  // When accelerated compositing is active, |callback| may be called
-  // asynchronously.
-  virtual void CopyFromBackingStore(const gfx::Rect& src_rect,
-                                    const gfx::Size& accelerated_dst_size,
-                                    const ReadbackRequestCallback& callback,
-                                    const SkColorType color_type) = 0;
-  // Ensures that the view does not drop the backing store even when hidden.
-  virtual bool CanCopyFromBackingStore() = 0;
-
   // Forwards the given message to the renderer. These are called by
   // the view when it has received a message.
   virtual void ForwardMouseEvent(
diff --git a/content/public/browser/render_widget_host_view.h b/content/public/browser/render_widget_host_view.h
index 71c693b..8d52b0f 100644
--- a/content/public/browser/render_widget_host_view.h
+++ b/content/public/browser/render_widget_host_view.h
@@ -10,8 +10,10 @@
 #include "base/strings/string16.h"
 #include "build/build_config.h"
 #include "content/common/content_export.h"
+#include "content/public/browser/readback_types.h"
 #include "third_party/WebKit/public/platform/WebInputEvent.h"
 #include "third_party/skia/include/core/SkColor.h"
+#include "third_party/skia/include/core/SkImageInfo.h"
 #include "ui/gfx/native_widget_types.h"
 
 namespace gfx {
@@ -20,6 +22,10 @@
 class Size;
 }
 
+namespace media {
+class VideoFrame;
+}
+
 namespace ui {
 class TextInputClient;
 class AcceleratedWidgetMac;
@@ -96,8 +102,6 @@
   virtual void Focus() = 0;
   // Returns true if the View currently has the focus.
   virtual bool HasFocus() const = 0;
-  // Returns true is the current display surface is available.
-  virtual bool IsSurfaceAvailableForCopy() const = 0;
 
   // Shows/hides the view.  These must always be called together in pairs.
   // It is not legal to call Hide() multiple times in a row.
@@ -151,6 +155,61 @@
   // visible viewport.
   virtual void SetInsets(const gfx::Insets& insets) = 0;
 
+  // Returns true if the current display surface is available, a prerequisite
+  // for CopyFromSurface() or CopyFromSurfaceToVideoFrame() to succeed.
+  virtual bool IsSurfaceAvailableForCopy() const = 0;
+
+  // Copies the given subset of the view's surface, optionally scales it, and
+  // returns the result as a bitmap via the provided callback. This is meant for
+  // one-off snapshots. For continuous video capture of the surface, please use
+  // BeginFrameSubscription().
+  //
+  // |src_rect| is either the subset of the view's surface, in view coordinates,
+  // or empty to indicate that all of it should be copied. This is NOT the same
+  // coordinate system as that used GetViewBounds() (https://crbug.com/73362).
+  //
+  // |output_size| is the size of the resulting bitmap, or empty to indicate no
+  // scaling is desired. If an empty size is provided, note that the resulting
+  // bitmap's size may not be the same as |src_rect.size()| due to the pixel
+  // scale used by the underlying device.
+  //
+  // |callback| is always invoked, at some point in the future, with success/
+  // fail status and an SkBitmap containing the copied pixel data. It may be
+  // called sychronously or asynchronously.
+  //
+  // If the view's renderer is suspended (see WasOccluded()), this may result in
+  // copying old data or failing.
+  virtual void CopyFromSurface(const gfx::Rect& src_rect,
+                               const gfx::Size& output_size,
+                               const ReadbackRequestCallback& callback,
+                               const SkColorType color_type) = 0;
+
+  // Copies the given subset of the view's surface, scales/letterboxes it, and
+  // returns the result within the provided media::VideoFrame. This is meant for
+  // one-off snapshots. For continuous video capture of the surface, please use
+  // BeginFrameSubscription().
+  //
+  // |src_rect| is either the subset of the view's surface, in view coordinates,
+  // or empty to indicate that all of it should be copied. This is NOT the same
+  // coordinate system as that used GetViewBounds() (https://crbug.com/73362).
+  //
+  // The |target| must use a pixel format supported by the platform. The size of
+  // the source region and the target together will determine how the content is
+  // positioned and scaled within the video frame. The aspect ratio of the
+  // source region will always be preserved, with letterboxing/pillarboxing
+  // applied to fill the entire frame.
+  //
+  // |callback| is always invoked, at some point in the future, with the region
+  // within |target| where the content was placed and a boolean success/fail
+  // flag. It may be called sychronously or asynchronously.
+  //
+  // If the view's renderer is suspended (see WasOccluded()), this may result in
+  // copying old data or failing.
+  virtual void CopyFromSurfaceToVideoFrame(
+      const gfx::Rect& src_rect,
+      scoped_refptr<media::VideoFrame> target,
+      const base::Callback<void(const gfx::Rect&, bool)>& callback) = 0;
+
   // Begin subscribing for presentation events and captured frames.
   // |subscriber| is now owned by this object, it will be called only on the
   // UI thread.
diff --git a/content/renderer/android/synchronous_compositor_frame_sink.cc b/content/renderer/android/synchronous_compositor_frame_sink.cc
index 7a8b023..f95e331 100644
--- a/content/renderer/android/synchronous_compositor_frame_sink.cc
+++ b/content/renderer/android/synchronous_compositor_frame_sink.cc
@@ -86,6 +86,7 @@
   void EnsureBackbuffer() override {}
   void DiscardBackbuffer() override {}
   void BindFramebuffer() override {}
+  void SetDrawRectangle(const gfx::Rect& rect) override {}
   void SwapBuffers(cc::OutputSurfaceFrame frame) override {}
   void Reshape(const gfx::Size& size,
                float scale_factor,
diff --git a/content/renderer/media/webrtc/OWNERS b/content/renderer/media/webrtc/OWNERS
index b67eda4..c31fa3cc 100644
--- a/content/renderer/media/webrtc/OWNERS
+++ b/content/renderer/media/webrtc/OWNERS
@@ -1 +1,3 @@
 sergeyu@chromium.org
+
+# COMPONENT: Blink>WebRTC
diff --git a/content/renderer/p2p/OWNERS b/content/renderer/p2p/OWNERS
index 5e2b3d6..70573c4 100644
--- a/content/renderer/p2p/OWNERS
+++ b/content/renderer/p2p/OWNERS
@@ -1,2 +1,4 @@
 sergeyu@chromium.org
 juberti@chromium.org
+
+# COMPONENT: Blink>WebRTC
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn
index 8058e76..d31f4685 100644
--- a/content/shell/BUILD.gn
+++ b/content/shell/BUILD.gn
@@ -369,7 +369,7 @@
   }
 
   if (is_linux) {
-    deps += [ "//third_party/freetype2" ]
+    deps += [ "//third_party/freetype-android:freetype" ]
   }
 
   if (!enable_plugins) {
diff --git a/content/test/test_render_view_host.cc b/content/test/test_render_view_host.cc
index 2b14348..b82403a 100644
--- a/content/test/test_render_view_host.cc
+++ b/content/test/test_render_view_host.cc
@@ -104,10 +104,6 @@
   return true;
 }
 
-bool TestRenderWidgetHostView::IsSurfaceAvailableForCopy() const {
-  return true;
-}
-
 void TestRenderWidgetHostView::Show() {
   is_showing_ = true;
   is_occluded_ = false;
@@ -140,25 +136,6 @@
   return gfx::Rect();
 }
 
-void TestRenderWidgetHostView::CopyFromCompositingSurface(
-    const gfx::Rect& src_subrect,
-    const gfx::Size& dst_size,
-    const ReadbackRequestCallback& callback,
-    const SkColorType preferred_color_type) {
-  callback.Run(SkBitmap(), content::READBACK_FAILED);
-}
-
-void TestRenderWidgetHostView::CopyFromCompositingSurfaceToVideoFrame(
-    const gfx::Rect& src_subrect,
-    const scoped_refptr<media::VideoFrame>& target,
-    const base::Callback<void(const gfx::Rect&, bool)>& callback) {
-  callback.Run(gfx::Rect(), false);
-}
-
-bool TestRenderWidgetHostView::CanCopyToVideoFrame() const {
-  return false;
-}
-
 bool TestRenderWidgetHostView::HasAcceleratedSurface(
       const gfx::Size& desired_size) {
   return false;
diff --git a/content/test/test_render_view_host.h b/content/test/test_render_view_host.h
index 6b14036..252a22d 100644
--- a/content/test/test_render_view_host.h
+++ b/content/test/test_render_view_host.h
@@ -71,7 +71,6 @@
   gfx::NativeViewAccessible GetNativeViewAccessible() override;
   ui::TextInputClient* GetTextInputClient() override;
   bool HasFocus() const override;
-  bool IsSurfaceAvailableForCopy() const override;
   void Show() override;
   void Hide() override;
   bool IsShowing() override;
@@ -103,16 +102,6 @@
                          int error_code) override;
   void Destroy() override;
   void SetTooltipText(const base::string16& tooltip_text) override {}
-  void CopyFromCompositingSurface(
-      const gfx::Rect& src_subrect,
-      const gfx::Size& dst_size,
-      const ReadbackRequestCallback& callback,
-      const SkColorType preferred_color_type) override;
-  void CopyFromCompositingSurfaceToVideoFrame(
-      const gfx::Rect& src_subrect,
-      const scoped_refptr<media::VideoFrame>& target,
-      const base::Callback<void(const gfx::Rect&, bool)>& callback) override;
-  bool CanCopyToVideoFrame() const override;
   bool HasAcceleratedSurface(const gfx::Size& desired_size) override;
   gfx::Rect GetBoundsInRootWindow() override;
   bool LockMouse() override;
diff --git a/courgette/disassembler_elf_32.cc b/courgette/disassembler_elf_32.cc
index b1c3f0b..e305b4ce 100644
--- a/courgette/disassembler_elf_32.cc
+++ b/courgette/disassembler_elf_32.cc
@@ -323,6 +323,70 @@
   return true;
 }
 
+CheckBool DisassemblerElf32::ParseAbs32Relocs() {
+  abs32_locations_.clear();
+
+  // Loop through sections for relocation sections
+  for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
+       ++section_id) {
+    const Elf32_Shdr* section_header = SectionHeader(section_id);
+
+    if (section_header->sh_type == SHT_REL) {
+      const Elf32_Rel* relocs_table =
+          reinterpret_cast<const Elf32_Rel*>(SectionBody(section_id));
+
+      int relocs_table_count =
+          section_header->sh_size / section_header->sh_entsize;
+
+      // Elf32_Word relocation_section_id = section_header->sh_info;
+
+      // Loop through relocation objects in the relocation section
+      for (int rel_id = 0; rel_id < relocs_table_count; ++rel_id) {
+        RVA rva;
+
+        // Quite a few of these conversions fail, and we simply skip
+        // them, that's okay.
+        if (RelToRVA(relocs_table[rel_id], &rva) && CheckSection(rva))
+          abs32_locations_.push_back(rva);
+      }
+    }
+  }
+
+  std::sort(abs32_locations_.begin(), abs32_locations_.end());
+  DCHECK(abs32_locations_.empty() || abs32_locations_.back() != kUnassignedRVA);
+  return true;
+}
+
+CheckBool DisassemblerElf32::ParseRel32RelocsFromSections() {
+  rel32_locations_.clear();
+  bool found_rel32 = false;
+
+  // Loop through sections for relocation sections
+  for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
+       ++section_id) {
+    const Elf32_Shdr* section_header = SectionHeader(section_id);
+
+    // Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0.
+    if (section_header->sh_type != SHT_PROGBITS || section_header->sh_addr == 0)
+      continue;
+
+    // Heuristic: Only consider ".text" section.
+    std::string section_name;
+    if (!SectionName(*section_header, &section_name))
+      return false;
+    if (section_name != ".text")
+      continue;
+
+    found_rel32 = true;
+    if (!ParseRel32RelocsFromSection(section_header))
+      return false;
+  }
+  if (!found_rel32)
+    VLOG(1) << "Warning: Found no rel32 addresses. Missing .text section?";
+
+  return true;
+}
+
 RvaVisitor* DisassemblerElf32::CreateAbs32TargetRvaVisitor() {
   return new RvaVisitor_Abs32(abs32_locations_, *this);
 }
@@ -541,41 +605,6 @@
   return true;
 }
 
-CheckBool DisassemblerElf32::ParseAbs32Relocs() {
-  abs32_locations_.clear();
-
-  // Loop through sections for relocation sections
-  for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
-       ++section_id) {
-    const Elf32_Shdr* section_header = SectionHeader(section_id);
-
-    if (section_header->sh_type == SHT_REL) {
-      const Elf32_Rel* relocs_table =
-          reinterpret_cast<const Elf32_Rel*>(SectionBody(section_id));
-
-      int relocs_table_count = section_header->sh_size /
-                               section_header->sh_entsize;
-
-      // Elf32_Word relocation_section_id = section_header->sh_info;
-
-      // Loop through relocation objects in the relocation section
-      for (int rel_id = 0; rel_id < relocs_table_count; ++rel_id) {
-        RVA rva;
-
-        // Quite a few of these conversions fail, and we simply skip
-        // them, that's okay.
-        if (RelToRVA(relocs_table[rel_id], &rva) && CheckSection(rva))
-          abs32_locations_.push_back(rva);
-      }
-    }
-  }
-
-  std::sort(abs32_locations_.begin(), abs32_locations_.end());
-  DCHECK(abs32_locations_.empty() ||
-         abs32_locations_.back() != kUnassignedRVA);
-  return true;
-}
-
 CheckBool DisassemblerElf32::CheckSection(RVA rva) {
   FileOffset file_offset = RVAToFileOffset(rva);
   if (file_offset == kNoFileOffset)
@@ -598,35 +627,4 @@
   return false;
 }
 
-CheckBool DisassemblerElf32::ParseRel32RelocsFromSections() {
-  rel32_locations_.clear();
-  bool found_rel32 = false;
-
-  // Loop through sections for relocation sections
-  for (Elf32_Half section_id = 0; section_id < SectionHeaderCount();
-       ++section_id) {
-    const Elf32_Shdr* section_header = SectionHeader(section_id);
-
-    // Some debug sections can have sh_type=SHT_PROGBITS but sh_addr=0.
-    if (section_header->sh_type != SHT_PROGBITS ||
-        section_header->sh_addr == 0)
-      continue;
-
-    // Heuristic: Only consider ".text" section.
-    std::string section_name;
-    if (!SectionName(*section_header, &section_name))
-      return false;
-    if (section_name != ".text")
-      continue;
-
-    found_rel32 = true;
-    if (!ParseRel32RelocsFromSection(section_header))
-      return false;
-  }
-  if (!found_rel32)
-    VLOG(1) << "Warning: Found no rel32 addresses. Missing .text section?";
-
-  return true;
-}
-
 }  // namespace courgette
diff --git a/courgette/disassembler_elf_32.h b/courgette/disassembler_elf_32.h
index 3cf42e2..fbd8a59 100644
--- a/courgette/disassembler_elf_32.h
+++ b/courgette/disassembler_elf_32.h
@@ -179,6 +179,11 @@
   virtual CheckBool ParseRel32RelocsFromSection(const Elf32_Shdr* section)
       WARN_UNUSED_RESULT = 0;
 
+  CheckBool ParseAbs32Relocs() WARN_UNUSED_RESULT;
+
+  // Extracts all rel32 TypedRVAs. Does not sort the result.
+  CheckBool ParseRel32RelocsFromSections() WARN_UNUSED_RESULT;
+
   // Disassembler interfaces.
   RvaVisitor* CreateAbs32TargetRvaVisitor() override;
   RvaVisitor* CreateRel32TargetRvaVisitor() override;
@@ -201,13 +206,8 @@
                               InstructionReceptor* receptor) const
       WARN_UNUSED_RESULT;
 
-  CheckBool ParseAbs32Relocs() WARN_UNUSED_RESULT;
-
   CheckBool CheckSection(RVA rva) WARN_UNUSED_RESULT;
 
-  // Extracts all rel32 TypedRVAs. Does not sort the result.
-  CheckBool ParseRel32RelocsFromSections() WARN_UNUSED_RESULT;
-
   const Elf32_Ehdr* header_;
 
   Elf32_Half section_header_table_size_;
diff --git a/courgette/disassembler_win32.cc b/courgette/disassembler_win32.cc
index e48b0f19..f677a06 100644
--- a/courgette/disassembler_win32.cc
+++ b/courgette/disassembler_win32.cc
@@ -365,6 +365,60 @@
   return true;
 }
 
+bool DisassemblerWin32::ParseAbs32Relocs() {
+  abs32_locations_.clear();
+  if (!ParseRelocs(&abs32_locations_))
+    return false;
+
+#if COURGETTE_HISTOGRAM_TARGETS
+  for (size_t i = 0; i < abs32_locations_.size(); ++i) {
+    RVA rva = abs32_locations_[i];
+    // The 4 bytes at the relocation are a reference to some address.
+    ++abs32_target_rvas_[PointerToTargetRVA(RVAToPointer(rva))];
+  }
+#endif
+  return true;
+}
+
+void DisassemblerWin32::ParseRel32RelocsFromSections() {
+  FileOffset file_offset = 0;
+  while (file_offset < length()) {
+    const Section* section = FindNextSection(file_offset);
+    if (section == nullptr)
+      break;
+    if (file_offset < section->file_offset_of_raw_data)
+      file_offset = section->file_offset_of_raw_data;
+    ParseRel32RelocsFromSection(section);
+    file_offset += section->size_of_raw_data;
+  }
+  std::sort(rel32_locations_.begin(), rel32_locations_.end());
+  DCHECK(rel32_locations_.empty() || rel32_locations_.back() != kUnassignedRVA);
+
+#if COURGETTE_HISTOGRAM_TARGETS
+  VLOG(1) << "abs32_locations_ " << abs32_locations_.size()
+          << "\nrel32_locations_ " << rel32_locations_.size()
+          << "\nabs32_target_rvas_ " << abs32_target_rvas_.size()
+          << "\nrel32_target_rvas_ " << rel32_target_rvas_.size();
+
+  int common = 0;
+  std::map<RVA, int>::iterator abs32_iter = abs32_target_rvas_.begin();
+  std::map<RVA, int>::iterator rel32_iter = rel32_target_rvas_.begin();
+  while (abs32_iter != abs32_target_rvas_.end() &&
+         rel32_iter != rel32_target_rvas_.end()) {
+    if (abs32_iter->first < rel32_iter->first) {
+      ++abs32_iter;
+    } else if (rel32_iter->first < abs32_iter->first) {
+      ++rel32_iter;
+    } else {
+      ++common;
+      ++abs32_iter;
+      ++rel32_iter;
+    }
+  }
+  VLOG(1) << "common " << common;
+#endif
+}
+
 RvaVisitor* DisassemblerWin32::CreateAbs32TargetRvaVisitor() {
   return new RvaVisitor_Abs32(abs32_locations_, *this);
 }
@@ -420,60 +474,6 @@
   return true;
 }
 
-bool DisassemblerWin32::ParseAbs32Relocs() {
-  abs32_locations_.clear();
-  if (!ParseRelocs(&abs32_locations_))
-    return false;
-
-#if COURGETTE_HISTOGRAM_TARGETS
-  for (size_t i = 0; i < abs32_locations_.size(); ++i) {
-    RVA rva = abs32_locations_[i];
-    // The 4 bytes at the relocation are a reference to some address.
-    ++abs32_target_rvas_[PointerToTargetRVA(RVAToPointer(rva))];
-  }
-#endif
-  return true;
-}
-
-void DisassemblerWin32::ParseRel32RelocsFromSections() {
-  FileOffset file_offset = 0;
-  while (file_offset < length()) {
-    const Section* section = FindNextSection(file_offset);
-    if (section == nullptr)
-      break;
-    if (file_offset < section->file_offset_of_raw_data)
-      file_offset = section->file_offset_of_raw_data;
-    ParseRel32RelocsFromSection(section);
-    file_offset += section->size_of_raw_data;
-  }
-  std::sort(rel32_locations_.begin(), rel32_locations_.end());
-  DCHECK(rel32_locations_.empty() || rel32_locations_.back() != kUnassignedRVA);
-
-#if COURGETTE_HISTOGRAM_TARGETS
-  VLOG(1) << "abs32_locations_ " << abs32_locations_.size()
-          << "\nrel32_locations_ " << rel32_locations_.size()
-          << "\nabs32_target_rvas_ " << abs32_target_rvas_.size()
-          << "\nrel32_target_rvas_ " << rel32_target_rvas_.size();
-
-  int common = 0;
-  std::map<RVA, int>::iterator abs32_iter = abs32_target_rvas_.begin();
-  std::map<RVA, int>::iterator rel32_iter = rel32_target_rvas_.begin();
-  while (abs32_iter != abs32_target_rvas_.end() &&
-         rel32_iter != rel32_target_rvas_.end()) {
-    if (abs32_iter->first < rel32_iter->first) {
-      ++abs32_iter;
-    } else if (rel32_iter->first < abs32_iter->first) {
-      ++rel32_iter;
-    } else {
-      ++common;
-      ++abs32_iter;
-      ++rel32_iter;
-    }
-  }
-  VLOG(1) << "common " << common;
-#endif
-}
-
 CheckBool DisassemblerWin32::ParseNonSectionFileRegion(
     FileOffset start_file_offset,
     FileOffset end_file_offset,
diff --git a/courgette/disassembler_win32.h b/courgette/disassembler_win32.h
index 76f57104..c6d986f 100644
--- a/courgette/disassembler_win32.h
+++ b/courgette/disassembler_win32.h
@@ -56,6 +56,9 @@
   // which will be checked against the detected one.
   static bool QuickDetect(const uint8_t* start, size_t length, uint16_t magic);
 
+  bool ParseAbs32Relocs();
+  void ParseRel32RelocsFromSections();
+
   // Disassembler interfaces.
   RvaVisitor* CreateAbs32TargetRvaVisitor() override;
   RvaVisitor* CreateRel32TargetRvaVisitor() override;
@@ -65,8 +68,6 @@
 
   CheckBool ParseFile(AssemblyProgram* target,
                       InstructionReceptor* receptor) const WARN_UNUSED_RESULT;
-  bool ParseAbs32Relocs();
-  void ParseRel32RelocsFromSections();
   virtual void ParseRel32RelocsFromSection(const Section* section) = 0;
 
   CheckBool ParseNonSectionFileRegion(FileOffset start_file_offset,
diff --git a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
index c12db754..6852ff5 100644
--- a/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
+++ b/extensions/browser/api/guest_view/web_view/web_view_internal_api.cc
@@ -311,10 +311,11 @@
   }
 
   is_guest_transparent_ = guest->allow_transparency();
-  return CaptureAsync(guest->web_contents(), image_details.get(),
-                      base::Bind(&WebViewInternalCaptureVisibleRegionFunction::
-                                     CopyFromBackingStoreComplete,
-                                 this));
+  return CaptureAsync(
+      guest->web_contents(), image_details.get(),
+      base::Bind(
+          &WebViewInternalCaptureVisibleRegionFunction::CopyFromSurfaceComplete,
+          this));
 }
 bool WebViewInternalCaptureVisibleRegionFunction::IsScreenshotEnabled() {
   // TODO(wjmaclean): Is it ok to always return true here?
diff --git a/extensions/browser/api/messaging/OWNERS b/extensions/browser/api/messaging/OWNERS
index 03bad0d6..c2707aec 100644
--- a/extensions/browser/api/messaging/OWNERS
+++ b/extensions/browser/api/messaging/OWNERS
@@ -1,2 +1,4 @@
 kelvinp@chromium.org
 sergeyu@chromium.org
+
+# COMPONENT: Platform>Extensions>API
diff --git a/extensions/browser/api/web_contents_capture_client.cc b/extensions/browser/api/web_contents_capture_client.cc
index 04f7c96..78ee2851 100644
--- a/extensions/browser/api/web_contents_capture_client.cc
+++ b/extensions/browser/api/web_contents_capture_client.cc
@@ -12,11 +12,8 @@
 #include "extensions/browser/extension_function.h"
 #include "extensions/common/constants.h"
 #include "third_party/skia/include/core/SkBitmap.h"
-#include "ui/display/display.h"
-#include "ui/display/screen.h"
 #include "ui/gfx/codec/jpeg_codec.h"
 #include "ui/gfx/codec/png_codec.h"
-#include "ui/gfx/geometry/size_conversions.h"
 
 using content::RenderWidgetHost;
 using content::RenderWidgetHostView;
@@ -53,30 +50,17 @@
 
   // TODO(miu): Account for fullscreen render widget?  http://crbug.com/419878
   RenderWidgetHostView* const view = web_contents->GetRenderWidgetHostView();
-  RenderWidgetHost* const host = view ? view->GetRenderWidgetHost() : nullptr;
-  if (!view || !host) {
+  if (!view) {
     OnCaptureFailure(FAILURE_REASON_VIEW_INVISIBLE);
     return false;
   }
-
-  // By default, the requested bitmap size is the view size in screen
-  // coordinates.  However, if there's more pixel detail available on the
-  // current system, increase the requested bitmap size to capture it all.
-  const gfx::Size view_size = view->GetViewBounds().size();
-  gfx::Size bitmap_size = view_size;
-  const gfx::NativeView native_view = view->GetNativeView();
-  display::Screen* const screen = display::Screen::GetScreen();
-  const float scale =
-      screen->GetDisplayNearestWindow(native_view).device_scale_factor();
-  if (scale > 1.0f)
-    bitmap_size = gfx::ScaleToCeiledSize(view_size, scale);
-
-  host->CopyFromBackingStore(gfx::Rect(view_size), bitmap_size, callback,
-                             kN32_SkColorType);
+  view->CopyFromSurface(gfx::Rect(),  // Copy entire surface area.
+                        gfx::Size(),  // Result contains device-level detail.
+                        callback, kN32_SkColorType);
   return true;
 }
 
-void WebContentsCaptureClient::CopyFromBackingStoreComplete(
+void WebContentsCaptureClient::CopyFromSurfaceComplete(
     const SkBitmap& bitmap,
     content::ReadbackResponse response) {
   if (response == content::READBACK_SUCCESS) {
diff --git a/extensions/browser/api/web_contents_capture_client.h b/extensions/browser/api/web_contents_capture_client.h
index 6535354..d27ed6e 100644
--- a/extensions/browser/api/web_contents_capture_client.h
+++ b/extensions/browser/api/web_contents_capture_client.h
@@ -41,8 +41,8 @@
   bool EncodeBitmap(const SkBitmap& bitmap, std::string* base64_result);
   virtual void OnCaptureFailure(FailureReason reason) = 0;
   virtual void OnCaptureSuccess(const SkBitmap& bitmap) = 0;
-  void CopyFromBackingStoreComplete(const SkBitmap& bitmap,
-                                    content::ReadbackResponse response);
+  void CopyFromSurfaceComplete(const SkBitmap& bitmap,
+                               content::ReadbackResponse response);
 
  private:
   // The format (JPEG vs PNG) of the resulting image.  Set in RunAsync().
diff --git a/extensions/browser/extension_function.h b/extensions/browser/extension_function.h
index 82503a7..b9289d8 100644
--- a/extensions/browser/extension_function.h
+++ b/extensions/browser/extension_function.h
@@ -84,10 +84,14 @@
 // supply a unique |histogramvalue| used for histograms of extension function
 // invocation (add new ones at the end of the enum in
 // extension_function_histogram_value.h).
-#define DECLARE_EXTENSION_FUNCTION(name, histogramvalue) \
-  public: static const char* function_name() { return name; } \
-  public: static extensions::functions::HistogramValue histogram_value() \
-    { return extensions::functions::histogramvalue; }
+#define DECLARE_EXTENSION_FUNCTION(name, histogramvalue)                     \
+ public:                                                                     \
+  static constexpr const char* function_name() { return name; }              \
+                                                                             \
+ public:                                                                     \
+  static constexpr extensions::functions::HistogramValue histogram_value() { \
+    return extensions::functions::histogramvalue;                            \
+  }
 
 // Traits that describe how ExtensionFunction should be deleted. This just calls
 // the virtual "Destruct" method on ExtensionFunction, allowing derived classes
diff --git a/extensions/browser/extension_function_registry.cc b/extensions/browser/extension_function_registry.cc
index a5b6b6b..75114e4 100644
--- a/extensions/browser/extension_function_registry.cc
+++ b/extensions/browser/extension_function_registry.cc
@@ -47,17 +47,12 @@
   return function;
 }
 
+void ExtensionFunctionRegistry::Register(const FactoryEntry& entry) {
+  factories_[entry.function_name_] = entry;
+}
+
 ExtensionFunctionRegistry::FactoryEntry::FactoryEntry()
     : factory_(0),
       function_name_(nullptr),
       histogram_value_(extensions::functions::UNKNOWN) {
 }
-
-ExtensionFunctionRegistry::FactoryEntry::FactoryEntry(
-    ExtensionFunctionFactory factory,
-    const char* function_name,
-    extensions::functions::HistogramValue histogram_value)
-    : factory_(factory),
-      function_name_(function_name),
-      histogram_value_(histogram_value) {
-}
diff --git a/extensions/browser/extension_function_registry.h b/extensions/browser/extension_function_registry.h
index 57b2138..128f5d0 100644
--- a/extensions/browser/extension_function_registry.h
+++ b/extensions/browser/extension_function_registry.h
@@ -26,6 +26,22 @@
 // create instances of them.
 class ExtensionFunctionRegistry {
  public:
+  struct FactoryEntry {
+   public:
+    explicit FactoryEntry();
+    constexpr FactoryEntry(
+        ExtensionFunctionFactory factory,
+        const char* function_name,
+        extensions::functions::HistogramValue histogram_value)
+        : factory_(factory),
+          function_name_(function_name),
+          histogram_value_(histogram_value) {}
+
+    ExtensionFunctionFactory factory_;
+    const char* function_name_;
+    extensions::functions::HistogramValue histogram_value_;
+  };
+
   static ExtensionFunctionRegistry* GetInstance();
   explicit ExtensionFunctionRegistry();
   virtual ~ExtensionFunctionRegistry();
@@ -38,26 +54,13 @@
   // Factory method for the ExtensionFunction registered as 'name'.
   ExtensionFunction* NewFunction(const std::string& name);
 
+  void Register(const FactoryEntry& entry);
   template <class T>
   void RegisterFunction() {
-    ExtensionFunctionFactory factory = &NewExtensionFunction<T>;
-    factories_[T::function_name()] =
-        FactoryEntry(factory, T::function_name(), T::histogram_value());
+    Register(FactoryEntry(&NewExtensionFunction<T>, T::function_name(),
+                          T::histogram_value()));
   }
 
-  struct FactoryEntry {
-   public:
-    explicit FactoryEntry();
-    explicit FactoryEntry(
-        ExtensionFunctionFactory factory,
-        const char* function_name,
-        extensions::functions::HistogramValue histogram_value);
-
-    ExtensionFunctionFactory factory_;
-    const char* function_name_;
-    extensions::functions::HistogramValue histogram_value_;
-  };
-
   typedef std::map<std::string, FactoryEntry> FactoryMap;
   FactoryMap factories_;
 };
diff --git a/gpu/BUILD.gn b/gpu/BUILD.gn
index 127c96fc..6b0dc6c 100644
--- a/gpu/BUILD.gn
+++ b/gpu/BUILD.gn
@@ -175,6 +175,7 @@
     "command_buffer/tests/texture_image_factory.h",
     "ipc/client/gpu_context_tests.h",
     "ipc/client/gpu_in_process_context_tests.cc",
+    "ipc/service/direct_composition_surface_win_unittest.cc",
   ]
 
   defines = [ "GL_GLEXT_PROTOTYPES" ]
diff --git a/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_set_draw_rectangle.txt b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_set_draw_rectangle.txt
new file mode 100644
index 0000000..5dd039d
--- /dev/null
+++ b/gpu/GLES2/extensions/CHROMIUM/CHROMIUM_set_draw_rectangle.txt
@@ -0,0 +1,52 @@
+Name
+
+    CHROMIUM_set_draw_rectangle
+
+Name Strings
+
+    GL_CHROMIUM_set_draw_rectangle
+
+Version
+
+    Last Modified Date: Jan 23, 2017
+
+Dependencies
+
+    OpenGL ES 2.0 is required.
+
+Overview
+
+    This extension allows a client to indicate what area is going to be drawn to.
+
+Issues
+
+    None
+
+New Tokens
+
+    None
+
+New Procedures and Functions
+
+    The command
+
+        glSetDrawRectangleCHROMIUM (GLint x, GLint y, GLint width, GLint height);
+
+    indicates that the client will fill in the entire rectangle specified of
+    the default framebuffer. This command can only be specified once per swap.
+    If the extension is supported, this function must be called before any
+    drawing to the default framebuffer. The contents of the framebuffer are
+    undefined after this command and must be filled in completely before a
+    swap happens. Rendering outside this rectangle causes undefined behavior,
+    and the scissor test must be enabled when drawing.
+
+    For the first call to this, and the first call after a resize, the
+    rectangle must be equal to the size of the entire buffer.
+
+Errors
+
+    None.
+
+New State
+
+    None.
diff --git a/gpu/GLES2/gl2chromium_autogen.h b/gpu/GLES2/gl2chromium_autogen.h
index 99bb510..f5bfb06b 100644
--- a/gpu/GLES2/gl2chromium_autogen.h
+++ b/gpu/GLES2/gl2chromium_autogen.h
@@ -384,5 +384,6 @@
   GLES2_GET_FUN(OverlayPromotionHintCHROMIUM)
 #define glSwapBuffersWithBoundsCHROMIUM \
   GLES2_GET_FUN(SwapBuffersWithBoundsCHROMIUM)
+#define glSetDrawRectangleCHROMIUM GLES2_GET_FUN(SetDrawRectangleCHROMIUM)
 
 #endif  // GPU_GLES2_GL2CHROMIUM_AUTOGEN_H_
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index 6c7ac0b..71e1647e 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -4526,6 +4526,10 @@
     'extension': 'CHROMIUM_path_rendering',
     'extension_flag': 'chromium_path_rendering',
   },
+  'SetDrawRectangleCHROMIUM': {
+    'decoder_func': 'DoSetDrawRectangleCHROMIUM',
+    'extension': 'CHROMIUM_set_draw_rectangle',
+  },
 }
 
 
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index de9c7da4..12d4643 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -1720,6 +1720,12 @@
                                                     const GLint* rects) {
   gles2::GetGLContext()->SwapBuffersWithBoundsCHROMIUM(count, rects);
 }
+void GL_APIENTRY GLES2SetDrawRectangleCHROMIUM(GLint x,
+                                               GLint y,
+                                               GLint width,
+                                               GLint height) {
+  gles2::GetGLContext()->SetDrawRectangleCHROMIUM(x, y, width, height);
+}
 
 namespace gles2 {
 
@@ -3023,6 +3029,10 @@
         reinterpret_cast<GLES2FunctionPointer>(glSwapBuffersWithBoundsCHROMIUM),
     },
     {
+        "glSetDrawRectangleCHROMIUM",
+        reinterpret_cast<GLES2FunctionPointer>(glSetDrawRectangleCHROMIUM),
+    },
+    {
         NULL, NULL,
     },
 };
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index 60951315..db32e55 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -3196,4 +3196,12 @@
   }
 }
 
+void SetDrawRectangleCHROMIUM(GLint x, GLint y, GLint width, GLint height) {
+  gles2::cmds::SetDrawRectangleCHROMIUM* c =
+      GetCmdSpace<gles2::cmds::SetDrawRectangleCHROMIUM>();
+  if (c) {
+    c->Init(x, y, width, height);
+  }
+}
+
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_CMD_HELPER_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index e67c89a..ae04ded 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -1207,4 +1207,9 @@
 
 void SwapBuffersWithBoundsCHROMIUM(GLsizei count, const GLint* rects) override;
 
+void SetDrawRectangleCHROMIUM(GLint x,
+                              GLint y,
+                              GLint width,
+                              GLint height) override;
+
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
index 7bd9f0d..73a9676 100644
--- a/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_impl_autogen.h
@@ -3513,4 +3513,15 @@
   CheckGLError();
 }
 
+void GLES2Implementation::SetDrawRectangleCHROMIUM(GLint x,
+                                                   GLint y,
+                                                   GLint width,
+                                                   GLint height) {
+  GPU_CLIENT_SINGLE_THREAD_CHECK();
+  GPU_CLIENT_LOG("[" << GetLogPrefix() << "] glSetDrawRectangleCHROMIUM(" << x
+                     << ", " << y << ", " << width << ", " << height << ")");
+  helper_->SetDrawRectangleCHROMIUM(x, y, width, height);
+  CheckGLError();
+}
+
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_IMPL_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
index bfc42bd..2e17662d 100644
--- a/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_unittest_autogen.h
@@ -3047,4 +3047,15 @@
   gl_->CoverageModulationCHROMIUM(GL_RGB);
   EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
 }
+
+TEST_F(GLES2ImplementationTest, SetDrawRectangleCHROMIUM) {
+  struct Cmds {
+    cmds::SetDrawRectangleCHROMIUM cmd;
+  };
+  Cmds expected;
+  expected.cmd.Init(1, 2, 3, 4);
+
+  gl_->SetDrawRectangleCHROMIUM(1, 2, 3, 4);
+  EXPECT_EQ(0, memcmp(&expected, commands_, sizeof(expected)));
+}
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_IMPLEMENTATION_UNITTEST_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_interface_autogen.h b/gpu/command_buffer/client/gles2_interface_autogen.h
index ba015e1..0883e2f 100644
--- a/gpu/command_buffer/client/gles2_interface_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_autogen.h
@@ -894,4 +894,8 @@
                                           GLint display_y) = 0;
 virtual void SwapBuffersWithBoundsCHROMIUM(GLsizei count,
                                            const GLint* rects) = 0;
+virtual void SetDrawRectangleCHROMIUM(GLint x,
+                                      GLint y,
+                                      GLint width,
+                                      GLint height) = 0;
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_interface_stub_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
index 37f34640..dbf6f11 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_autogen.h
@@ -867,4 +867,8 @@
                                   GLint display_x,
                                   GLint display_y) override;
 void SwapBuffersWithBoundsCHROMIUM(GLsizei count, const GLint* rects) override;
+void SetDrawRectangleCHROMIUM(GLint x,
+                              GLint y,
+                              GLint width,
+                              GLint height) override;
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
index dec13b3..8d3cc0e 100644
--- a/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_interface_stub_impl_autogen.h
@@ -1170,4 +1170,8 @@
 void GLES2InterfaceStub::SwapBuffersWithBoundsCHROMIUM(
     GLsizei /* count */,
     const GLint* /* rects */) {}
+void GLES2InterfaceStub::SetDrawRectangleCHROMIUM(GLint /* x */,
+                                                  GLint /* y */,
+                                                  GLint /* width */,
+                                                  GLint /* height */) {}
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_INTERFACE_STUB_IMPL_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
index bfbe6394..6d09d94 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_autogen.h
@@ -867,4 +867,8 @@
                                   GLint display_x,
                                   GLint display_y) override;
 void SwapBuffersWithBoundsCHROMIUM(GLsizei count, const GLint* rects) override;
+void SetDrawRectangleCHROMIUM(GLint x,
+                              GLint y,
+                              GLint width,
+                              GLint height) override;
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_TRACE_IMPLEMENTATION_AUTOGEN_H_
diff --git a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
index f06bcd6..459910e 100644
--- a/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
+++ b/gpu/command_buffer/client/gles2_trace_implementation_impl_autogen.h
@@ -2503,4 +2503,12 @@
   gl_->SwapBuffersWithBoundsCHROMIUM(count, rects);
 }
 
+void GLES2TraceImplementation::SetDrawRectangleCHROMIUM(GLint x,
+                                                        GLint y,
+                                                        GLint width,
+                                                        GLint height) {
+  TRACE_EVENT_BINARY_EFFICIENT0("gpu", "GLES2Trace::SetDrawRectangleCHROMIUM");
+  gl_->SetDrawRectangleCHROMIUM(x, y, width, height);
+}
+
 #endif  // GPU_COMMAND_BUFFER_CLIENT_GLES2_TRACE_IMPLEMENTATION_IMPL_AUTOGEN_H_
diff --git a/gpu/command_buffer/cmd_buffer_functions.txt b/gpu/command_buffer/cmd_buffer_functions.txt
index e0db0f5..6d30de9 100644
--- a/gpu/command_buffer/cmd_buffer_functions.txt
+++ b/gpu/command_buffer/cmd_buffer_functions.txt
@@ -363,3 +363,6 @@
 GL_APICALL void         GL_APIENTRY glOverlayPromotionHintCHROMIUM (GLidBindTexture texture, GLboolean promotion_hint, GLint display_x, GLint display_y);
 
 GL_APICALL void         GL_APIENTRY glSwapBuffersWithBoundsCHROMIUM (GLsizei count, const GLint* rects);
+
+// Extension CHROMIUM_set_draw_rectangle
+GL_APICALL void         GL_APIENTRY glSetDrawRectangleCHROMIUM (GLint x, GLint y, GLint width, GLint height);
diff --git a/gpu/command_buffer/common/capabilities.h b/gpu/command_buffer/common/capabilities.h
index 15de84c..b6445c37 100644
--- a/gpu/command_buffer/common/capabilities.h
+++ b/gpu/command_buffer/common/capabilities.h
@@ -154,6 +154,7 @@
   bool disable_multisampling_color_mask_usage = false;
   bool disable_webgl_rgb_multisampling_usage = false;
   bool gpu_rasterization = false;
+  bool set_draw_rectangle = false;
 
   // When this parameter is true, a CHROMIUM image created with RGB format will
   // actually have RGBA format. The client is responsible for handling most of
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index 6113c95..1bf837a 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -15689,4 +15689,49 @@
     offsetof(SwapBuffersWithBoundsCHROMIUMImmediate, count) == 4,
     "offset of SwapBuffersWithBoundsCHROMIUMImmediate count should be 4");
 
+struct SetDrawRectangleCHROMIUM {
+  typedef SetDrawRectangleCHROMIUM ValueType;
+  static const CommandId kCmdId = kSetDrawRectangleCHROMIUM;
+  static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+  static const uint8_t cmd_flags = CMD_FLAG_SET_TRACE_LEVEL(3);
+
+  static uint32_t ComputeSize() {
+    return static_cast<uint32_t>(sizeof(ValueType));  // NOLINT
+  }
+
+  void SetHeader() { header.SetCmd<ValueType>(); }
+
+  void Init(GLint _x, GLint _y, GLint _width, GLint _height) {
+    SetHeader();
+    x = _x;
+    y = _y;
+    width = _width;
+    height = _height;
+  }
+
+  void* Set(void* cmd, GLint _x, GLint _y, GLint _width, GLint _height) {
+    static_cast<ValueType*>(cmd)->Init(_x, _y, _width, _height);
+    return NextCmdAddress<ValueType>(cmd);
+  }
+
+  gpu::CommandHeader header;
+  int32_t x;
+  int32_t y;
+  int32_t width;
+  int32_t height;
+};
+
+static_assert(sizeof(SetDrawRectangleCHROMIUM) == 20,
+              "size of SetDrawRectangleCHROMIUM should be 20");
+static_assert(offsetof(SetDrawRectangleCHROMIUM, header) == 0,
+              "offset of SetDrawRectangleCHROMIUM header should be 0");
+static_assert(offsetof(SetDrawRectangleCHROMIUM, x) == 4,
+              "offset of SetDrawRectangleCHROMIUM x should be 4");
+static_assert(offsetof(SetDrawRectangleCHROMIUM, y) == 8,
+              "offset of SetDrawRectangleCHROMIUM y should be 8");
+static_assert(offsetof(SetDrawRectangleCHROMIUM, width) == 12,
+              "offset of SetDrawRectangleCHROMIUM width should be 12");
+static_assert(offsetof(SetDrawRectangleCHROMIUM, height) == 16,
+              "offset of SetDrawRectangleCHROMIUM height should be 16");
+
 #endif  // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_AUTOGEN_H_
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
index 3c62164..ab231ac 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -5261,4 +5261,19 @@
       next_cmd, sizeof(cmd) + RoundSizeToMultipleOfEntries(sizeof(data)));
 }
 
+TEST_F(GLES2FormatTest, SetDrawRectangleCHROMIUM) {
+  cmds::SetDrawRectangleCHROMIUM& cmd =
+      *GetBufferAs<cmds::SetDrawRectangleCHROMIUM>();
+  void* next_cmd = cmd.Set(&cmd, static_cast<GLint>(11), static_cast<GLint>(12),
+                           static_cast<GLint>(13), static_cast<GLint>(14));
+  EXPECT_EQ(static_cast<uint32_t>(cmds::SetDrawRectangleCHROMIUM::kCmdId),
+            cmd.header.command);
+  EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+  EXPECT_EQ(static_cast<GLint>(11), cmd.x);
+  EXPECT_EQ(static_cast<GLint>(12), cmd.y);
+  EXPECT_EQ(static_cast<GLint>(13), cmd.width);
+  EXPECT_EQ(static_cast<GLint>(14), cmd.height);
+  CheckBytesWrittenMatchesExpectedSize(next_cmd, sizeof(cmd));
+}
+
 #endif  // GPU_COMMAND_BUFFER_COMMON_GLES2_CMD_FORMAT_TEST_AUTOGEN_H_
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
index 081de2d..1dc54cf9 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -329,7 +329,8 @@
   OP(GetFragDataIndexEXT)                                  /* 570 */ \
   OP(UniformMatrix4fvStreamTextureMatrixCHROMIUMImmediate) /* 571 */ \
   OP(OverlayPromotionHintCHROMIUM)                         /* 572 */ \
-  OP(SwapBuffersWithBoundsCHROMIUMImmediate)               /* 573 */
+  OP(SwapBuffersWithBoundsCHROMIUMImmediate)               /* 573 */ \
+  OP(SetDrawRectangleCHROMIUM)                             /* 574 */
 
 enum CommandId {
   kOneBeforeStartPoint =
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index 67eab70d..aad78dd 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -1693,6 +1693,9 @@
                                       GLint display_x,
                                       GLint display_y);
 
+  // Wrapper for glSetDrawRectangleCHROMIUM
+  void DoSetDrawRectangleCHROMIUM(GLint x, GLint y, GLint width, GLint height);
+
   // Wrapper for glReadBuffer
   void DoReadBuffer(GLenum src);
 
@@ -2349,6 +2352,7 @@
   bool supports_swap_buffers_with_bounds_;
   bool supports_commit_overlay_planes_;
   bool supports_async_swap_;
+  bool supports_set_draw_rectangle_ = false;
 
   // These flags are used to override the state of the shared feature_info_
   // member.  Because the same FeatureInfo instance may be shared among many
@@ -3563,6 +3567,9 @@
 
   supports_async_swap_ = surface->SupportsAsyncSwap();
 
+  supports_set_draw_rectangle_ =
+      !offscreen && surface->SupportsSetDrawRectangle();
+
   if (workarounds().reverse_point_sprite_coord_origin) {
     glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
   }
@@ -3737,6 +3744,7 @@
   bool is_offscreen = !!offscreen_target_frame_buffer_.get();
   caps.flips_vertically = !is_offscreen && surface_->FlipsVertically();
   caps.msaa_is_slow = workarounds().msaa_is_slow;
+  caps.set_draw_rectangle = supports_set_draw_rectangle_;
 
   caps.blend_equation_advanced =
       feature_info_->feature_flags().blend_equation_advanced;
@@ -8689,6 +8697,28 @@
   image->NotifyPromotionHint(promotion_hint != GL_FALSE, display_x, display_y);
 }
 
+void GLES2DecoderImpl::DoSetDrawRectangleCHROMIUM(GLint x,
+                                                  GLint y,
+                                                  GLint width,
+                                                  GLint height) {
+  Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_DRAW_FRAMEBUFFER);
+  if (framebuffer) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glSetDrawRectangleCHROMIUM",
+                       "framebuffer must not be bound");
+    return;
+  }
+  if (!supports_set_draw_rectangle_) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glSetDrawRectangleCHROMIUM",
+                       "surface doesn't support SetDrawRectangle");
+    return;
+  }
+  gfx::Rect rect(x, y, width, height);
+  if (!surface_->SetDrawRectangle(rect)) {
+    LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glSetDrawRectangleCHROMIUM",
+                       "failed on surface");
+  }
+}
+
 void GLES2DecoderImpl::DoReadBuffer(GLenum src) {
   Framebuffer* framebuffer = GetFramebufferInfoForTarget(GL_READ_FRAMEBUFFER);
   if (framebuffer) {
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index 4b5befb..9fbab40 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -5158,6 +5158,20 @@
   return error::kNoError;
 }
 
+error::Error GLES2DecoderImpl::HandleSetDrawRectangleCHROMIUM(
+    uint32_t immediate_data_size,
+    const volatile void* cmd_data) {
+  const volatile gles2::cmds::SetDrawRectangleCHROMIUM& c =
+      *static_cast<const volatile gles2::cmds::SetDrawRectangleCHROMIUM*>(
+          cmd_data);
+  GLint x = static_cast<GLint>(c.x);
+  GLint y = static_cast<GLint>(c.y);
+  GLint width = static_cast<GLint>(c.width);
+  GLint height = static_cast<GLint>(c.height);
+  DoSetDrawRectangleCHROMIUM(x, y, width, height);
+  return error::kNoError;
+}
+
 bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) {
   switch (cap) {
     case GL_BLEND:
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
index 22292f7..fb4b4090 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doer_prototypes.h
@@ -954,3 +954,7 @@
                                             GLboolean promotion_hint,
                                             GLint display_x,
                                             GLint display_y);
+error::Error DoSetDrawRectangleCHROMIUM(GLint x,
+                                        GLint y,
+                                        GLint width,
+                                        GLint height);
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 fd1e5596..8604e0e0 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_doers.cc
@@ -3468,5 +3468,14 @@
   return error::kNoError;
 }
 
+error::Error GLES2DecoderPassthroughImpl::DoSetDrawRectangleCHROMIUM(
+    GLint x,
+    GLint y,
+    GLint width,
+    GLint height) {
+  NOTIMPLEMENTED();
+  return error::kNoError;
+}
+
 }  // namespace gles2
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
index f7c1e65..37639206 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_passthrough_handlers_autogen.cc
@@ -4368,5 +4368,22 @@
   return error::kNoError;
 }
 
+error::Error GLES2DecoderPassthroughImpl::HandleSetDrawRectangleCHROMIUM(
+    uint32_t immediate_data_size,
+    const volatile void* cmd_data) {
+  const volatile gles2::cmds::SetDrawRectangleCHROMIUM& c =
+      *static_cast<const volatile gles2::cmds::SetDrawRectangleCHROMIUM*>(
+          cmd_data);
+  GLint x = static_cast<GLint>(c.x);
+  GLint y = static_cast<GLint>(c.y);
+  GLint width = static_cast<GLint>(c.width);
+  GLint height = static_cast<GLint>(c.height);
+  error::Error error = DoSetDrawRectangleCHROMIUM(x, y, width, height);
+  if (error != error::kNoError) {
+    return error;
+  }
+  return error::kNoError;
+}
+
 }  // namespace gles2
 }  // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_4_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_4_autogen.h
index 3621b3cb..264c667 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_4_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_4_autogen.h
@@ -24,4 +24,13 @@
   EXPECT_EQ(error::kNoError, ExecuteImmediateCmd(cmd, sizeof(temp)));
   EXPECT_EQ(GL_NO_ERROR, GetGLError());
 }
+
+TEST_P(GLES2DecoderTest4, SetDrawRectangleCHROMIUMValidArgs) {
+  EXPECT_CALL(*gl_, SetDrawRectangleCHROMIUM(1, 2, 3, 4));
+  SpecializedSetup<cmds::SetDrawRectangleCHROMIUM, 0>(true);
+  cmds::SetDrawRectangleCHROMIUM cmd;
+  cmd.Init(1, 2, 3, 4);
+  EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
+  EXPECT_EQ(GL_NO_ERROR, GetGLError());
+}
 #endif  // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_4_AUTOGEN_H_
diff --git a/gpu/config/gpu_driver_bug_list_json.cc b/gpu/config/gpu_driver_bug_list_json.cc
index 48cd484e..850b3eb8 100644
--- a/gpu/config/gpu_driver_bug_list_json.cc
+++ b/gpu/config/gpu_driver_bug_list_json.cc
@@ -19,7 +19,7 @@
 {
   "name": "gpu driver bug list",
   // Please update the version number whenever you change this file.
-  "version": "9.31",
+  "version": "9.32",
   "entries": [
     {
       "id": 1,
@@ -2323,9 +2323,9 @@
     {
       "id": 214,
       "description": "Certain versions of Qualcomm driver don't setup scissor state correctly when FBO0 is bound.",
-      "cr_bugs": [670607],
+      "cr_bugs": [670607, 696627],
       "gl_vendor": "Qualcomm.*",
-      "machine_model_name": ["Nexus 7"],
+      "machine_model_name": ["Nexus 7", "KFTHWI", "KFSAWI", "KFAPWI", "KFTHWA", "KFSAWA", "KFAPWA"],
       "features": [
         "force_update_scissor_state_when_binding_fbo0"
       ]
diff --git a/gpu/config/software_rendering_list_json.cc b/gpu/config/software_rendering_list_json.cc
index ad2f9731f..1cadf12 100644
--- a/gpu/config/software_rendering_list_json.cc
+++ b/gpu/config/software_rendering_list_json.cc
@@ -18,7 +18,7 @@
 {
   "name": "software rendering list",
   // Please update the version number whenever you change this file.
-  "version": "12.18",
+  "version": "12.19",
   "entries": [
     {
       "id": 1,
@@ -1235,7 +1235,7 @@
     },
     {
       "id": 122,
-      "description": "GPU rasterization should only be enabled on NVIDIA Pascal and Maxwell, Intel Haswell+, and AMD RX-R2 GPUs for now.",
+      "description": "GPU rasterization should only be enabled on NVIDIA and Intel DX11+, and AMD RX-R2 GPUs for now.",
       "cr_bugs": [643850],
       "os": {
         "type": "win"
@@ -1249,27 +1249,7 @@
           "pixel_shader_version": {
             "op": ">=",
             "value": "5.0"
-          },
-          "device_id": ["0x1340", "0x1341", "0x1344", "0x1346", "0x1347",
-                        "0x1348", "0x1349", "0x134d", "0x134e", "0x134f",
-                        "0x137a", "0x137d", "0x1380", "0x1381", "0x1382",
-                        "0x1389", "0x1390", "0x1391", "0x1392", "0x1393",
-                        "0x1398", "0x139a", "0x139b", "0x139c", "0x139d",
-                        "0x13b0", "0x13b1", "0x13b2", "0x13b9", "0x13ba",
-                        "0x13bb", "0x13bc", "0x13bd", "0x13c0", "0x13c1",
-                        "0x13c2", "0x13c3", "0x13d7", "0x13d8", "0x13d9",
-                        "0x13da", "0x13f0", "0x13f1", "0x13f2", "0x13f3",
-                        "0x13f8", "0x13f9", "0x13fa", "0x1401", "0x1402",
-                        "0x1406", "0x1407", "0x1427", "0x1430", "0x1431",
-                        "0x1617", "0x1618", "0x1619", "0x161a", "0x1667",
-                        "0x17c2", "0x17c8", "0x17f0", "0x17fd", "0x15f0",
-                        "0x15f1", "0x15f8", "0x15f9", "0x1725", "0x172e",
-                        "0x172f", "0x1b00", "0x1b01", "0x1b70", "0x1b78",
-                        "0x1b80", "0x1b81", "0x1b82", "0x1b83", "0x1bb0",
-                        "0x1bb1", "0x1bb4", "0x1c00", "0x1c01", "0x1c02",
-                        "0x1c03", "0x1c30", "0x1c70", "0x1c80", "0x1c81",
-                        "0x1c82", "0x1ca7", "0x1ca8", "0x1caa", "0x1d01"]
-
+          }
         },
         {
           "vendor_id": "0x8086",
@@ -1484,6 +1464,37 @@
       "features": [
         "webgl2"
       ]
+    },
+    {
+      "id": 136,
+      "description": "GPU rasterization is blacklisted on NVidia Fermi architecture for now.",
+      "cr_bugs": [643850],
+      "os": {
+        "type": "win"
+      },
+      "vendor_id": "0x10de",
+      "device_id": ["0x06c0", "0x06c4", "0x06ca", "0x06cb", "0x06cd", "0x06d1",
+                    "0x06d2", "0x06d8", "0x06d9", "0x06da", "0x06dc", "0x06dd",
+                    "0x06de", "0x06df", "0x0e22", "0x0e23", "0x0e24", "0x0e30",
+                    "0x0e31", "0x0e3a", "0x0e3b", "0x1200", "0x1201", "0x1202",
+                    "0x1203", "0x1205", "0x1206", "0x1207", "0x1208", "0x1210",
+                    "0x1211", "0x1212", "0x1213", "0x0dc0", "0x0dc4", "0x0dc5",
+                    "0x0dc6", "0x0dcd", "0x0dce", "0x0dd1", "0x0dd2", "0x0dd3",
+                    "0x0dd6", "0x0dd8", "0x0dda", "0x1241", "0x1243", "0x1244",
+                    "0x1245", "0x1246", "0x1247", "0x1248", "0x1249", "0x124b",
+                    "0x124d", "0x1251", "0x0de0", "0x0de1", "0x0de2", "0x0de3",
+                    "0x0de4", "0x0de5", "0x0de8", "0x0de9", "0x0dea", "0x0deb",
+                    "0x0dec", "0x0ded", "0x0dee", "0x0def", "0x0df0", "0x0df1",
+                    "0x0df2", "0x0df3", "0x0df4", "0x0df5", "0x0df6", "0x0df7",
+                    "0x0df8", "0x0df9", "0x0dfa", "0x0dfc", "0x0f00", "0x0f01",
+                    "0x1080", "0x1081", "0x1082", "0x1084", "0x1086", "0x1087",
+                    "0x1088", "0x1089", "0x108b", "0x1091", "0x109a", "0x109b",
+                    "0x1040", "0x1042", "0x1048", "0x1049", "0x104a", "0x1050",
+                    "0x1051", "0x1052", "0x1054", "0x1055", "0x1056", "0x1057",
+                    "0x1058", "0x1059", "0x105a", "0x107d", "0x1140"],
+      "features": [
+        "gpu_rasterization"
+      ]
     }
   ]
 }
diff --git a/gpu/ipc/common/gpu_command_buffer_traits_multi.h b/gpu/ipc/common/gpu_command_buffer_traits_multi.h
index bb52e5b..941b936 100644
--- a/gpu/ipc/common/gpu_command_buffer_traits_multi.h
+++ b/gpu/ipc/common/gpu_command_buffer_traits_multi.h
@@ -127,6 +127,7 @@
   IPC_STRUCT_TRAITS_MEMBER(gpu_rasterization)
   IPC_STRUCT_TRAITS_MEMBER(chromium_image_rgb_emulation)
   IPC_STRUCT_TRAITS_MEMBER(emulate_rgb_buffer_with_rgba)
+  IPC_STRUCT_TRAITS_MEMBER(set_draw_rectangle)
 
   IPC_STRUCT_TRAITS_MEMBER(major_version)
   IPC_STRUCT_TRAITS_MEMBER(minor_version)
diff --git a/gpu/ipc/service/direct_composition_surface_win.cc b/gpu/ipc/service/direct_composition_surface_win.cc
index d425561..317964e5 100644
--- a/gpu/ipc/service/direct_composition_surface_win.cc
+++ b/gpu/ipc/service/direct_composition_surface_win.cc
@@ -4,23 +4,62 @@
 
 #include "gpu/ipc/service/direct_composition_surface_win.h"
 
+#include "base/optional.h"
 #include "gpu/ipc/service/gpu_channel_manager.h"
 #include "gpu/ipc/service/gpu_channel_manager_delegate.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/gl/egl_util.h"
+#include "ui/gl/gl_angle_util_win.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_surface_egl.h"
+#include "ui/gl/scoped_make_current.h"
+
+#ifndef EGL_ANGLE_flexible_surface_compatibility
+#define EGL_ANGLE_flexible_surface_compatibility 1
+#define EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE 0x33A6
+#endif /* EGL_ANGLE_flexible_surface_compatibility */
+
+#ifndef EGL_ANGLE_d3d_texture_client_buffer
+#define EGL_ANGLE_d3d_texture_client_buffer 1
+#define EGL_D3D_TEXTURE_ANGLE 0x33A3
+#endif /* EGL_ANGLE_d3d_texture_client_buffer */
 
 namespace gpu {
+namespace {
+
+// This class is used to make sure a specified surface isn't current, and upon
+// destruction it will make the surface current again if it had been before.
+class ScopedReleaseCurrent {
+ public:
+  explicit ScopedReleaseCurrent(gl::GLSurface* this_surface) {
+    gl::GLContext* current_context = gl::GLContext::GetCurrent();
+    bool was_current =
+        current_context && current_context->IsCurrent(this_surface);
+    if (was_current) {
+      make_current_.emplace(current_context, this_surface);
+      current_context->ReleaseCurrent(this_surface);
+    }
+  }
+
+ private:
+  base::Optional<ui::ScopedMakeCurrent> make_current_;
+};
+
+// Only one DirectComposition surface can be rendered into at a time. Track
+// here which IDCompositionSurface is being rendered into. If another context
+// is made current, then this surface will be suspended.
+IDCompositionSurface* g_current_surface;
+
+}  // namespace
 
 DirectCompositionSurfaceWin::DirectCompositionSurfaceWin(
     base::WeakPtr<ImageTransportSurfaceDelegate> delegate,
     HWND parent_window)
-    : gl::GLSurfaceEGL(),
-      child_window_(delegate, parent_window),
-      window_(nullptr),
-      surface_(0),
-      first_swap_(true) {}
+    : gl::GLSurfaceEGL(), child_window_(delegate, parent_window) {}
+
+DirectCompositionSurfaceWin::~DirectCompositionSurfaceWin() {
+  Destroy();
+}
 
 bool DirectCompositionSurfaceWin::InitializeNativeWindow() {
   if (window_)
@@ -31,14 +70,40 @@
   return result;
 }
 
+bool DirectCompositionSurfaceWin::Initialize(
+    std::unique_ptr<gfx::VSyncProvider> vsync_provider) {
+  vsync_provider_ = std::move(vsync_provider);
+  return Initialize(gl::GLSurfaceFormat());
+}
+
 bool DirectCompositionSurfaceWin::Initialize(gl::GLSurfaceFormat format) {
+  d3d11_device_ = gl::QueryD3D11DeviceObjectFromANGLE();
+  dcomp_device_ = gl::QueryDirectCompositionDevice(d3d11_device_);
+  if (!dcomp_device_)
+    return false;
+
   EGLDisplay display = GetDisplay();
   if (!window_) {
     if (!InitializeNativeWindow()) {
-      LOG(ERROR) << "Failed to initialize native window";
+      DLOG(ERROR) << "Failed to initialize native window";
       return false;
     }
   }
+
+  base::win::ScopedComPtr<IDCompositionDesktopDevice> desktop_device;
+  dcomp_device_.QueryInterface(desktop_device.Receive());
+
+  HRESULT hr = desktop_device->CreateTargetForHwnd(window_, TRUE,
+                                                   dcomp_target_.Receive());
+  if (FAILED(hr))
+    return false;
+
+  hr = dcomp_device_->CreateVisual(visual_.Receive());
+  if (FAILED(hr))
+    return false;
+
+  dcomp_target_->SetRoot(visual_.get());
+
   std::vector<EGLint> pbuffer_attribs;
   pbuffer_attribs.push_back(EGL_WIDTH);
   pbuffer_attribs.push_back(1);
@@ -46,20 +111,60 @@
   pbuffer_attribs.push_back(1);
 
   pbuffer_attribs.push_back(EGL_NONE);
-  surface_ = eglCreatePbufferSurface(display, GetConfig(), &pbuffer_attribs[0]);
-  CHECK(!!surface_);
+  default_surface_ =
+      eglCreatePbufferSurface(display, GetConfig(), &pbuffer_attribs[0]);
+  CHECK(!!default_surface_);
+
+  InitializeSurface();
 
   return true;
 }
 
-void DirectCompositionSurfaceWin::Destroy() {
-  if (surface_) {
-    if (!eglDestroySurface(GetDisplay(), surface_)) {
-      LOG(ERROR) << "eglDestroySurface failed with error "
-                 << ui::GetLastEGLErrorString();
-    }
-    surface_ = NULL;
+void DirectCompositionSurfaceWin::InitializeSurface() {
+  ScopedReleaseCurrent release_current(this);
+  ReleaseDrawTexture();
+  dcomp_surface_.Release();
+  HRESULT hr = dcomp_device_->CreateSurface(
+      size_.width(), size_.height(), DXGI_FORMAT_B8G8R8A8_UNORM,
+      DXGI_ALPHA_MODE_PREMULTIPLIED, dcomp_surface_.Receive());
+  has_been_rendered_to_ = false;
+
+  CHECK(SUCCEEDED(hr));
+}
+
+void DirectCompositionSurfaceWin::ReleaseDrawTexture() {
+  if (real_surface_) {
+    eglDestroySurface(GetDisplay(), real_surface_);
+    real_surface_ = nullptr;
   }
+  if (draw_texture_) {
+    draw_texture_.Release();
+    HRESULT hr = dcomp_surface_->EndDraw();
+    CHECK(SUCCEEDED(hr));
+  }
+  if (dcomp_surface_ == g_current_surface)
+    g_current_surface = nullptr;
+}
+
+void DirectCompositionSurfaceWin::Destroy() {
+  if (default_surface_) {
+    if (!eglDestroySurface(GetDisplay(), default_surface_)) {
+      DLOG(ERROR) << "eglDestroySurface failed with error "
+                  << ui::GetLastEGLErrorString();
+    }
+    default_surface_ = nullptr;
+  }
+  if (real_surface_) {
+    if (!eglDestroySurface(GetDisplay(), real_surface_)) {
+      DLOG(ERROR) << "eglDestroySurface failed with error "
+                  << ui::GetLastEGLErrorString();
+    }
+    real_surface_ = nullptr;
+  }
+  if (dcomp_surface_ == g_current_surface)
+    g_current_surface = nullptr;
+  draw_texture_.Release();
+  dcomp_surface_.Release();
 }
 
 gfx::Size DirectCompositionSurfaceWin::GetSize() {
@@ -71,7 +176,7 @@
 }
 
 void* DirectCompositionSurfaceWin::GetHandle() {
-  return surface_;
+  return real_surface_ ? real_surface_ : default_surface_;
 }
 
 bool DirectCompositionSurfaceWin::Resize(const gfx::Size& size,
@@ -87,11 +192,20 @@
     return false;
   }
   size_ = size;
+  InitializeSurface();
+
   return true;
 }
 
 gfx::SwapResult DirectCompositionSurfaceWin::SwapBuffers() {
-  CommitAndClearPendingOverlays();
+  {
+    ScopedReleaseCurrent release_current(this);
+    ReleaseDrawTexture();
+    visual_->SetContent(dcomp_surface_.get());
+
+    CommitAndClearPendingOverlays();
+    dcomp_device_->Commit();
+  }
   // Force the driver to finish drawing before clearing the contents to
   // transparent, to reduce or eliminate the period of time where the contents
   // have flashed black.
@@ -107,7 +221,11 @@
                                                            int y,
                                                            int width,
                                                            int height) {
+  ScopedReleaseCurrent release_current(this);
+  ReleaseDrawTexture();
+  visual_->SetContent(dcomp_surface_.get());
   CommitAndClearPendingOverlays();
+  dcomp_device_->Commit();
   child_window_.ClearInvalidContents();
   return gfx::SwapResult::SWAP_ACK;
 }
@@ -116,12 +234,6 @@
   return vsync_provider_.get();
 }
 
-bool DirectCompositionSurfaceWin::Initialize(
-    std::unique_ptr<gfx::VSyncProvider> vsync_provider) {
-  vsync_provider_ = std::move(vsync_provider);
-  return Initialize(gl::GLSurfaceFormat());
-}
-
 bool DirectCompositionSurfaceWin::ScheduleOverlayPlane(
     int z_order,
     gfx::OverlayTransform transform,
@@ -133,10 +245,84 @@
   return true;
 }
 
+bool DirectCompositionSurfaceWin::CommitAndClearPendingOverlays() {
+  pending_overlays_.clear();
+  return true;
+}
+
+bool DirectCompositionSurfaceWin::FlipsVertically() const {
+  return true;
+}
+
 bool DirectCompositionSurfaceWin::SupportsPostSubBuffer() {
   return true;
 }
 
+bool DirectCompositionSurfaceWin::OnMakeCurrent(gl::GLContext* context) {
+  if (g_current_surface != dcomp_surface_) {
+    if (g_current_surface) {
+      HRESULT hr = g_current_surface->SuspendDraw();
+      CHECK(SUCCEEDED(hr));
+      g_current_surface = nullptr;
+    }
+    if (draw_texture_) {
+      HRESULT hr = dcomp_surface_->ResumeDraw();
+      CHECK(SUCCEEDED(hr));
+      g_current_surface = dcomp_surface_.get();
+    }
+  }
+  return true;
+}
+
+bool DirectCompositionSurfaceWin::SupportsSetDrawRectangle() const {
+  return true;
+}
+
+bool DirectCompositionSurfaceWin::SetDrawRectangle(const gfx::Rect& rectangle) {
+  if (draw_texture_)
+    return false;
+  if (!gfx::Rect(size_).Contains(rectangle)) {
+    DLOG(ERROR) << "Draw rectangle must be contained within size of surface";
+    return false;
+  }
+  if (gfx::Rect(size_) != rectangle && !has_been_rendered_to_) {
+    DLOG(ERROR) << "First draw to surface must draw to everything";
+    return false;
+  }
+
+  DCHECK(!real_surface_);
+  CHECK(!g_current_surface);
+  ScopedReleaseCurrent release_current(this);
+
+  RECT rect = rectangle.ToRECT();
+  // TODO(jbauman): Use update_offset
+  POINT update_offset;
+
+  HRESULT hr = dcomp_surface_->BeginDraw(
+      &rect, IID_PPV_ARGS(draw_texture_.Receive()), &update_offset);
+  CHECK(SUCCEEDED(hr));
+  has_been_rendered_to_ = true;
+
+  g_current_surface = dcomp_surface_.get();
+
+  std::vector<EGLint> pbuffer_attribs{
+      EGL_WIDTH,
+      size_.width(),
+      EGL_HEIGHT,
+      size_.height(),
+      EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE,
+      EGL_TRUE,
+      EGL_NONE};
+
+  EGLClientBuffer buffer =
+      reinterpret_cast<EGLClientBuffer>(draw_texture_.get());
+  real_surface_ = eglCreatePbufferFromClientBuffer(
+      GetDisplay(), EGL_D3D_TEXTURE_ANGLE, buffer, GetConfig(),
+      &pbuffer_attribs[0]);
+
+  return true;
+}
+
 DirectCompositionSurfaceWin::Overlay::Overlay(int z_order,
                                               gfx::OverlayTransform transform,
                                               scoped_refptr<gl::GLImage> image,
@@ -152,11 +338,4 @@
 
 DirectCompositionSurfaceWin::Overlay::~Overlay() {}
 
-bool DirectCompositionSurfaceWin::CommitAndClearPendingOverlays() {
-  pending_overlays_.clear();
-  return true;
-}
-
-DirectCompositionSurfaceWin::~DirectCompositionSurfaceWin() {}
-
 }  // namespace gpu
diff --git a/gpu/ipc/service/direct_composition_surface_win.h b/gpu/ipc/service/direct_composition_surface_win.h
index 01fdbb18..6b7fec7 100644
--- a/gpu/ipc/service/direct_composition_surface_win.h
+++ b/gpu/ipc/service/direct_composition_surface_win.h
@@ -5,17 +5,21 @@
 #ifndef GPU_IPC_SERVICE_DIRECT_COMPOSITION_SURFACE_WIN_H_
 #define GPU_IPC_SERVICE_DIRECT_COMPOSITION_SURFACE_WIN_H_
 
+#include <d3d11.h>
+#include <dcomp.h>
+#include <windows.h>
+
 #include "base/memory/weak_ptr.h"
+#include "base/win/scoped_comptr.h"
+#include "gpu/gpu_export.h"
 #include "gpu/ipc/service/child_window_win.h"
 #include "gpu/ipc/service/image_transport_surface_delegate.h"
 #include "ui/gl/gl_image.h"
 #include "ui/gl/gl_surface_egl.h"
 
-#include <windows.h>
-
 namespace gpu {
 
-class DirectCompositionSurfaceWin : public gl::GLSurfaceEGL {
+class GPU_EXPORT DirectCompositionSurfaceWin : public gl::GLSurfaceEGL {
  public:
   DirectCompositionSurfaceWin(
       base::WeakPtr<ImageTransportSurfaceDelegate> delegate,
@@ -41,7 +45,11 @@
                             gl::GLImage* image,
                             const gfx::Rect& bounds_rect,
                             const gfx::RectF& crop_rect) override;
+  bool FlipsVertically() const override;
   bool SupportsPostSubBuffer() override;
+  bool OnMakeCurrent(gl::GLContext* context) override;
+  bool SupportsSetDrawRectangle() const override;
+  bool SetDrawRectangle(const gfx::Rect& rect) override;
 
   bool Initialize(std::unique_ptr<gfx::VSyncProvider> vsync_provider);
 
@@ -67,16 +75,35 @@
   };
 
   bool CommitAndClearPendingOverlays();
+  void InitializeSurface();
+  void ReleaseDrawTexture();
 
   ChildWindowWin child_window_;
 
-  HWND window_;
-  EGLSurface surface_;
-  gfx::Size size_;
-  bool first_swap_;
+  HWND window_ = nullptr;
+  // This is a placeholder surface used when not rendering to the
+  // DirectComposition surface.
+  EGLSurface default_surface_ = 0;
+
+  // This is the real surface representing the backbuffer. It may be null
+  // outside of a BeginDraw/EndDraw pair.
+  EGLSurface real_surface_ = 0;
+  gfx::Size size_ = gfx::Size(1, 1);
+  bool first_swap_ = true;
   std::unique_ptr<gfx::VSyncProvider> vsync_provider_;
   std::vector<Overlay> pending_overlays_;
 
+  base::win::ScopedComPtr<ID3D11Device> d3d11_device_;
+  base::win::ScopedComPtr<IDCompositionDevice2> dcomp_device_;
+  base::win::ScopedComPtr<IDCompositionTarget> dcomp_target_;
+  base::win::ScopedComPtr<IDCompositionVisual2> visual_;
+  base::win::ScopedComPtr<IDCompositionSurface> dcomp_surface_;
+  base::win::ScopedComPtr<ID3D11Texture2D> draw_texture_;
+
+  // Keep track of whether the texture has been rendered to, as the first draw
+  // to it must overwrite the entire thing.
+  bool has_been_rendered_to_ = false;
+
   DISALLOW_COPY_AND_ASSIGN(DirectCompositionSurfaceWin);
 };
 
diff --git a/gpu/ipc/service/direct_composition_surface_win_unittest.cc b/gpu/ipc/service/direct_composition_surface_win_unittest.cc
new file mode 100644
index 0000000..3e43906
--- /dev/null
+++ b/gpu/ipc/service/direct_composition_surface_win_unittest.cc
@@ -0,0 +1,102 @@
+// 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 "gpu/ipc/service/direct_composition_surface_win.h"
+#include "base/memory/weak_ptr.h"
+#include "base/run_loop.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/base/win/hidden_window.h"
+#include "ui/gl/gl_angle_util_win.h"
+#include "ui/gl/gl_context.h"
+#include "ui/gl/init/gl_factory.h"
+
+namespace gpu {
+namespace {
+
+class TestImageTransportSurfaceDelegate
+    : public ImageTransportSurfaceDelegate,
+      public base::SupportsWeakPtr<TestImageTransportSurfaceDelegate> {
+ public:
+  ~TestImageTransportSurfaceDelegate() override {}
+
+  // ImageTransportSurfaceDelegate implementation.
+  void DidCreateAcceleratedSurfaceChildWindow(
+      SurfaceHandle parent_window,
+      SurfaceHandle child_window) override {}
+  void DidSwapBuffersComplete(SwapBuffersCompleteParams params) override {}
+  const gles2::FeatureInfo* GetFeatureInfo() const override { return nullptr; }
+  void SetLatencyInfoCallback(const LatencyInfoCallback& callback) override {}
+  void UpdateVSyncParameters(base::TimeTicks timebase,
+                             base::TimeDelta interval) override {}
+  void AddFilter(IPC::MessageFilter* message_filter) override {}
+  int32_t GetRouteID() const override { return 0; }
+};
+
+TEST(DirectCompositionSurfaceTest, TestMakeCurrent) {
+  if (!gl::QueryDirectCompositionDevice(
+          gl::QueryD3D11DeviceObjectFromANGLE())) {
+    LOG(WARNING)
+        << "GL implementation not using DirectComposition, skipping test.";
+    return;
+  }
+
+  TestImageTransportSurfaceDelegate delegate;
+
+  scoped_refptr<DirectCompositionSurfaceWin> surface(
+      new DirectCompositionSurfaceWin(delegate.AsWeakPtr(),
+                                      ui::GetHiddenWindow()));
+  EXPECT_TRUE(surface->Initialize());
+
+  scoped_refptr<gl::GLContext> context =
+      gl::init::CreateGLContext(nullptr, surface.get(), gl::GLContextAttribs());
+  EXPECT_TRUE(surface->Resize(gfx::Size(100, 100), 1.0, true));
+
+  // First SetDrawRectangle must be full size of surface.
+  EXPECT_FALSE(surface->SetDrawRectangle(gfx::Rect(0, 0, 50, 50)));
+  EXPECT_TRUE(surface->SetDrawRectangle(gfx::Rect(0, 0, 100, 100)));
+
+  // SetDrawRectangle can't be called again until swap.
+  EXPECT_FALSE(surface->SetDrawRectangle(gfx::Rect(0, 0, 100, 100)));
+
+  EXPECT_TRUE(context->MakeCurrent(surface.get()));
+  EXPECT_EQ(gfx::SwapResult::SWAP_ACK, surface->SwapBuffers());
+
+  EXPECT_TRUE(context->IsCurrent(surface.get()));
+
+  // SetDrawRectangle must be contained within surface.
+  EXPECT_FALSE(surface->SetDrawRectangle(gfx::Rect(0, 0, 101, 101)));
+  EXPECT_TRUE(surface->SetDrawRectangle(gfx::Rect(0, 0, 100, 100)));
+  EXPECT_TRUE(context->IsCurrent(surface.get()));
+
+  EXPECT_TRUE(surface->Resize(gfx::Size(50, 50), 1.0, true));
+  EXPECT_TRUE(surface->SetDrawRectangle(gfx::Rect(0, 0, 50, 50)));
+  EXPECT_TRUE(context->IsCurrent(surface.get()));
+
+  scoped_refptr<DirectCompositionSurfaceWin> surface2(
+      new DirectCompositionSurfaceWin(delegate.AsWeakPtr(),
+                                      ui::GetHiddenWindow()));
+  EXPECT_TRUE(surface2->Initialize());
+
+  scoped_refptr<gl::GLContext> context2 = gl::init::CreateGLContext(
+      nullptr, surface2.get(), gl::GLContextAttribs());
+  EXPECT_TRUE(context2->MakeCurrent(surface2.get()));
+  EXPECT_TRUE(surface2->Resize(gfx::Size(100, 100), 1.0, true));
+  // The previous IDCompositionSurface should be suspended when another
+  // surface is being drawn to.
+  EXPECT_TRUE(surface2->SetDrawRectangle(gfx::Rect(0, 0, 100, 100)));
+  EXPECT_TRUE(context2->IsCurrent(surface2.get()));
+
+  // It should be possible to switch back to the previous surface and
+  // unsuspend it.
+  EXPECT_TRUE(context->MakeCurrent(surface.get()));
+
+  context2 = nullptr;
+  surface2 = nullptr;
+  context = nullptr;
+  surface = nullptr;
+  base::RunLoop().RunUntilIdle();
+}
+
+}  // namespace
+}  // namespace gpu
diff --git a/gpu/ipc/service/gpu_vsync_provider_win.cc b/gpu/ipc/service/gpu_vsync_provider_win.cc
index dccb122..cae8e38 100644
--- a/gpu/ipc/service/gpu_vsync_provider_win.cc
+++ b/gpu/ipc/service/gpu_vsync_provider_win.cc
@@ -7,6 +7,7 @@
 #include <string>
 
 #include "base/atomicops.h"
+#include "base/debug/alias.h"
 #include "base/strings/stringprintf.h"
 #include "base/threading/thread.h"
 #include "base/trace_event/trace_event.h"
@@ -20,12 +21,16 @@
 namespace gpu {
 
 namespace {
+// Default interval used when no v-sync interval comes from DWM.
+const int kDefaultTimerBasedInterval = 16666;
+
 // from <D3dkmthk.h>
 typedef LONG NTSTATUS;
 typedef UINT D3DKMT_HANDLE;
 typedef UINT D3DDDI_VIDEO_PRESENT_SOURCE_ID;
 
 #define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
+#define STATUS_GRAPHICS_PRESENT_OCCLUDED ((NTSTATUS)0xC01E0006L)
 
 typedef struct _D3DKMT_OPENADAPTERFROMHDC {
   HDC hDc;
@@ -63,9 +68,6 @@
   void Enable(bool enabled);
   void StartRunningVSyncOnThread();
   void WaitForVSyncOnThread();
-  void SendVSyncUpdate(base::TimeTicks now,
-                       base::TimeTicks timestamp,
-                       base::TimeDelta interval);
   bool BelongsToWorkerThread();
 
  private:
@@ -75,7 +77,15 @@
   void Reschedule();
   void OpenAdapter(const wchar_t* device_name);
   void CloseAdapter();
-  bool WaitForVBlankEvent();
+  NTSTATUS WaitForVBlankEvent();
+
+  void SendGpuVSyncUpdate(base::TimeTicks now,
+                          base::TimeTicks timestamp,
+                          base::TimeDelta interval);
+  void InvokeCallbackAndReschedule(base::TimeTicks timestamp,
+                                   base::TimeDelta interval);
+  void ScheduleDelayBasedVSync(base::TimeTicks timebase,
+                               base::TimeDelta interval);
 
   // Specifies whether background tasks are running.
   // This can be set on background thread only.
@@ -190,19 +200,30 @@
     OpenAdapter(monitor_info.szDevice);
   }
 
-  // Crash if WaitForVBlankEvent fails to avoid spinning the loop.
-  CHECK(WaitForVBlankEvent());
+  NTSTATUS wait_result = WaitForVBlankEvent();
+  if (wait_result != STATUS_SUCCESS) {
+    if (wait_result == STATUS_GRAPHICS_PRESENT_OCCLUDED) {
+      // This may be triggered by the monitor going into sleep.
+      // Use timer based mechanism as a backup, start with getting VSync
+      // parameters to determine timebase and interval.
+      // TODO(stanisc): Consider a slower v-sync rate in this particular case.
+      vsync_provider_->GetVSyncParameters(base::Bind(
+          &GpuVSyncWorker::ScheduleDelayBasedVSync, base::Unretained(this)));
+      return;
+    } else {
+      base::debug::Alias(&wait_result);
+      CHECK(false);
+    }
+  }
 
   vsync_provider_->GetVSyncParameters(
-      base::Bind(&GpuVSyncWorker::SendVSyncUpdate, base::Unretained(this),
+      base::Bind(&GpuVSyncWorker::SendGpuVSyncUpdate, base::Unretained(this),
                  base::TimeTicks::Now()));
-
-  Reschedule();
 }
 
-void GpuVSyncWorker::SendVSyncUpdate(base::TimeTicks now,
-                                     base::TimeTicks timestamp,
-                                     base::TimeDelta interval) {
+void GpuVSyncWorker::SendGpuVSyncUpdate(base::TimeTicks now,
+                                        base::TimeTicks timestamp,
+                                        base::TimeDelta interval) {
   base::TimeDelta adjustment;
 
   if (!(timestamp.is_null() || interval.is_zero())) {
@@ -219,17 +240,17 @@
     timestamp = now;
   }
 
-  TRACE_EVENT1("gpu", "GpuVSyncWorker::SendVSyncUpdate", "adjustment",
+  TRACE_EVENT1("gpu", "GpuVSyncWorker::SendGpuVSyncUpdate", "adjustment",
                adjustment.ToInternalValue());
 
-  if (base::subtle::NoBarrier_Load(&enabled_)) {
-    callback_.Run(timestamp, interval);
-  }
+  InvokeCallbackAndReschedule(timestamp, interval);
 }
 
-void GpuVSyncWorker::Reschedule() {
-  // Restart the task if still enabled.
+void GpuVSyncWorker::InvokeCallbackAndReschedule(base::TimeTicks timestamp,
+                                                 base::TimeDelta interval) {
+  // Send update and restart the task if still enabled.
   if (base::subtle::NoBarrier_Load(&enabled_)) {
+    callback_.Run(timestamp, interval);
     task_runner()->PostTask(FROM_HERE,
                             base::Bind(&GpuVSyncWorker::WaitForVSyncOnThread,
                                        base::Unretained(this)));
@@ -238,6 +259,24 @@
   }
 }
 
+void GpuVSyncWorker::ScheduleDelayBasedVSync(base::TimeTicks timebase,
+                                             base::TimeDelta interval) {
+  // This is called only when WaitForVBlankEvent fails due to monitor going to
+  // sleep.  Use a delay based v-sync as a back-up.
+  if (interval.is_zero()) {
+    interval = base::TimeDelta::FromMicroseconds(kDefaultTimerBasedInterval);
+  }
+
+  base::TimeTicks now = base::TimeTicks::Now();
+  base::TimeTicks next_vsync = now.SnappedToNextTick(timebase, interval);
+
+  task_runner()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&GpuVSyncWorker::InvokeCallbackAndReschedule,
+                 base::Unretained(this), next_vsync, interval),
+      next_vsync - now);
+}
+
 void GpuVSyncWorker::OpenAdapter(const wchar_t* device_name) {
   DCHECK_EQ(0u, current_adapter_handle_);
 
@@ -269,16 +308,14 @@
   }
 }
 
-bool GpuVSyncWorker::WaitForVBlankEvent() {
+NTSTATUS GpuVSyncWorker::WaitForVBlankEvent() {
   D3DKMT_WAITFORVERTICALBLANKEVENT wait_for_vertical_blank_event_data;
   wait_for_vertical_blank_event_data.hAdapter = current_adapter_handle_;
   wait_for_vertical_blank_event_data.hDevice = 0;
   wait_for_vertical_blank_event_data.VidPnSourceId = current_source_id_;
 
-  NTSTATUS result =
-      wait_for_vertical_blank_event_ptr_(&wait_for_vertical_blank_event_data);
-
-  return result == STATUS_SUCCESS;
+  return wait_for_vertical_blank_event_ptr_(
+      &wait_for_vertical_blank_event_data);
 }
 
 // MessageFilter class for sending and receiving IPC messages
diff --git a/headless/BUILD.gn b/headless/BUILD.gn
index 757d671..bc66c58 100644
--- a/headless/BUILD.gn
+++ b/headless/BUILD.gn
@@ -287,6 +287,7 @@
     "//components/security_state/core",
     "//content/public/app:both",
     "//content/public/browser",
+    "//content/public/child:child",
     "//content/public/common",
     "//content/public/common:service_names",
     "//net",
diff --git a/headless/lib/browser/headless_content_browser_client.cc b/headless/lib/browser/headless_content_browser_client.cc
index ade0c60f..5876199 100644
--- a/headless/lib/browser/headless_content_browser_client.cc
+++ b/headless/lib/browser/headless_content_browser_client.cc
@@ -28,6 +28,7 @@
 #include "headless/lib/headless_macros.h"
 #include "storage/browser/quota/quota_settings.h"
 #include "ui/base/resource/resource_bundle.h"
+#include "ui/gfx/switches.h"
 
 #if defined(HEADLESS_USE_BREAKPAD)
 #include "base/debug/leak_annotations.h"
@@ -186,6 +187,7 @@
 void HeadlessContentBrowserClient::AppendExtraCommandLineSwitches(
     base::CommandLine* command_line,
     int child_process_id) {
+  command_line->AppendSwitch(switches::kHeadless);
 #if defined(HEADLESS_USE_BREAKPAD)
   // This flag tells child processes to also turn on crash reporting.
   if (breakpad::IsCrashReporterEnabled())
diff --git a/ios/chrome/browser/payments/js_payment_request_manager.h b/ios/chrome/browser/payments/js_payment_request_manager.h
index 3e95970..0fded2c 100644
--- a/ios/chrome/browser/payments/js_payment_request_manager.h
+++ b/ios/chrome/browser/payments/js_payment_request_manager.h
@@ -6,6 +6,7 @@
 #define IOS_CHROME_BROWSER_PAYMENTS_JS_PAYMENT_REQUEST_MANAGER_H_
 
 #include "base/strings/string16.h"
+#include "ios/chrome/browser/procedural_block_types.h"
 #import "ios/web/public/web_state/js/crw_js_injection_manager.h"
 
 namespace web {
@@ -29,30 +30,35 @@
 - (void)resolveRequestPromiseWithPaymentResponse:
             (const web::PaymentResponse&)paymentResponse
                                completionHandler:
-                                   (void (^)(BOOL))completionHandler;
+                                   (ProceduralBlockWithBool)completionHandler;
 
 // Rejects the JavaScript promise associated with the current PaymentRequest
 // with the supplied |errorMessage|. If |completionHandler| is not nil, it will
 // be invoked with YES after the operation has completed successfully or with NO
 // otherwise.
 - (void)rejectRequestPromiseWithErrorMessage:(NSString*)errorMessage
-                           completionHandler:(void (^)(BOOL))completionHandler;
+                           completionHandler:
+                               (ProceduralBlockWithBool)completionHandler;
+
+// Resolves the promise returned by PaymentRequest.prototype.abort.
+- (void)resolveAbortPromiseWithCompletionHandler:
+    (ProceduralBlockWithBool)completionHandler;
 
 // Resolves the JavaScript promise associated with the current PaymentResponse.
 // If |completionHandler| is not nil, it will be invoked with YES after the
 // operation has completed successfully or with NO otherwise.
 - (void)resolveResponsePromiseWithCompletionHandler:
-    (void (^)(BOOL))completionHandler;
+    (ProceduralBlockWithBool)completionHandler;
 
 // Updates the shippingAddress property on the PaymentRequest object and
 // dispatches a shippingaddresschange event.
 - (void)updateShippingAddress:(const web::PaymentAddress&)shippingAddress
-            completionHandler:(void (^)(BOOL))completionHanlder;
+            completionHandler:(ProceduralBlockWithBool)completionHanlder;
 
 // Updates the shippingOption property on the PaymentRequest object and
 // dispatches a shippingoptionchange event.
 - (void)updateShippingOption:(const web::PaymentShippingOption&)shippingOption
-           completionHandler:(void (^)(BOOL))completionHanlder;
+           completionHandler:(ProceduralBlockWithBool)completionHanlder;
 
 @end
 
diff --git a/ios/chrome/browser/payments/js_payment_request_manager.mm b/ios/chrome/browser/payments/js_payment_request_manager.mm
index 48337a4..5a19c91 100644
--- a/ios/chrome/browser/payments/js_payment_request_manager.mm
+++ b/ios/chrome/browser/payments/js_payment_request_manager.mm
@@ -31,7 +31,7 @@
 // indicating whether an error occurred. The resolve and reject functions in the
 // Payment Request JavaScript do not return values so the result is ignored.
 - (void)executeScript:(NSString*)script
-    completionHandler:(void (^)(BOOL))completionHandler;
+    completionHandler:(ProceduralBlockWithBool)completionHandler;
 
 @end
 
@@ -44,7 +44,7 @@
 - (void)resolveRequestPromiseWithPaymentResponse:
             (const web::PaymentResponse&)paymentResponse
                                completionHandler:
-                                   (void (^)(BOOL))completionHandler {
+                                   (ProceduralBlockWithBool)completionHandler {
   std::unique_ptr<base::DictionaryValue> paymentResponseData =
       paymentResponse.ToDictionaryValue();
   std::string paymentResponseDataJSON;
@@ -57,7 +57,8 @@
 }
 
 - (void)rejectRequestPromiseWithErrorMessage:(NSString*)errorMessage
-                           completionHandler:(void (^)(BOOL))completionHandler {
+                           completionHandler:
+                               (ProceduralBlockWithBool)completionHandler {
   NSString* script = [NSString
       stringWithFormat:
           @"__gCrWeb['paymentRequestManager'].rejectRequestPromise(%@)",
@@ -65,15 +66,21 @@
   [self executeScript:script completionHandler:completionHandler];
 }
 
+- (void)resolveAbortPromiseWithCompletionHandler:
+    (ProceduralBlockWithBool)completionHandler {
+  NSString* script = @"__gCrWeb['paymentRequestManager'].resolveAbortPromise()";
+  [self executeScript:script completionHandler:completionHandler];
+}
+
 - (void)resolveResponsePromiseWithCompletionHandler:
-    (void (^)(BOOL))completionHandler {
+    (ProceduralBlockWithBool)completionHandler {
   NSString* script =
       @"__gCrWeb['paymentRequestManager'].resolveResponsePromise()";
   [self executeScript:script completionHandler:completionHandler];
 }
 
 - (void)updateShippingAddress:(const web::PaymentAddress&)shippingAddress
-            completionHandler:(void (^)(BOOL))completionHanlder {
+            completionHandler:(ProceduralBlockWithBool)completionHanlder {
   std::unique_ptr<base::DictionaryValue> shippingAddressData =
       shippingAddress.ToDictionaryValue();
   std::string shippingAddressDataJSON;
@@ -86,7 +93,7 @@
 }
 
 - (void)updateShippingOption:(const web::PaymentShippingOption&)shippingOption
-           completionHandler:(void (^)(BOOL))completionHanlder {
+           completionHandler:(ProceduralBlockWithBool)completionHanlder {
   NSString* script =
       [NSString stringWithFormat:@"__gCrWeb['paymentRequestManager']."
                                  @"updateShippingOptionAndDispatchEvent('%@')",
@@ -95,7 +102,7 @@
 }
 
 - (void)executeScript:(NSString*)script
-    completionHandler:(void (^)(BOOL))completionHandler {
+    completionHandler:(ProceduralBlockWithBool)completionHandler {
   [self executeJavaScript:script
         completionHandler:^(id result, NSError* error) {
           if (completionHandler)
diff --git a/ios/chrome/browser/payments/payment_request_manager.mm b/ios/chrome/browser/payments/payment_request_manager.mm
index aed2a47..bd65e35 100644
--- a/ios/chrome/browser/payments/payment_request_manager.mm
+++ b/ios/chrome/browser/payments/payment_request_manager.mm
@@ -19,6 +19,7 @@
 #import "ios/chrome/browser/payments/js_payment_request_manager.h"
 #include "ios/chrome/browser/payments/payment_request.h"
 #import "ios/chrome/browser/payments/payment_request_coordinator.h"
+#include "ios/chrome/browser/procedural_block_types.h"
 #include "ios/web/public/favicon_status.h"
 #include "ios/web/public/navigation_item.h"
 #include "ios/web/public/navigation_manager.h"
@@ -101,6 +102,11 @@
 // Synchronous method executed by -asynchronouslyEnablePaymentRequest:
 - (void)doEnablePaymentRequest:(BOOL)enabled;
 
+// Terminates the pending request with an error message and dismisses the UI.
+// Invokes the callback once the request has been terminated.
+- (void)terminateRequestWithErrorMessage:(NSString*)errorMessage
+                                callback:(ProceduralBlockWithBool)callback;
+
 // Initialize the PaymentRequest JavaScript.
 - (void)initializeWebViewForPaymentRequest;
 
@@ -112,10 +118,19 @@
 // invocation was successful.
 - (BOOL)handleRequestShow:(const base::DictionaryValue&)message;
 
+// Handles invocations of PaymentRequest.abort(). Returns YES if the invocation
+// was successful.
+- (BOOL)handleRequestAbort:(const base::DictionaryValue&)message;
+
+// Called by |_updateEventTimeoutTimer|, displays an error message. Upon
+// dismissal of the error message, cancels the Payment Request as if it was
+// performend by the user.
+- (BOOL)displayErrorThenCancelRequest;
+
 // Called by |_paymentResponseTimeoutTimer|, invokes handleResponseComplete:
 // as if PaymentResponse.complete() was invoked with the default "unknown"
 // argument.
-- (BOOL)handleResponseComplete;
+- (BOOL)doResponseComplete;
 
 // Handles invocations of PaymentResponse.complete(). Returns YES if the
 // invocation was successful.
@@ -130,7 +145,7 @@
 // presenting the Payment Request UI.
 - (void)setUnblockEventQueueTimer;
 
-// Establishes a timer that calls handleResponseComplete when it times out. Per
+// Establishes a timer that calls doResponseComplete when it times out. Per
 // the spec, if the page does not call PaymentResponse.complete() within some
 // timeout period, user agents may behave as if the complete() method was
 // called with no arguments.
@@ -209,13 +224,15 @@
 }
 
 - (void)cancelRequest {
-  [self cancelRequestWithErrorMessage:@"Request canceled."];
+  [self terminateRequestWithErrorMessage:@"The payment request was canceled."
+                                callback:nil];
 }
 
-- (void)cancelRequestWithErrorMessage:(NSString*)errorMessage {
+- (void)terminateRequestWithErrorMessage:(NSString*)errorMessage
+                                callback:(ProceduralBlockWithBool)callback {
   [self dismissUI];
   [_paymentRequestJsManager rejectRequestPromiseWithErrorMessage:errorMessage
-                                               completionHandler:nil];
+                                               completionHandler:callback];
 }
 
 - (void)close {
@@ -289,8 +306,8 @@
   if (command == "paymentRequest.requestShow") {
     return [self handleRequestShow:JSONCommand];
   }
-  if (command == "paymentRequest.requestCancel") {
-    return [self handleRequestCancel];
+  if (command == "paymentRequest.requestAbort") {
+    return [self handleRequestAbort:JSONCommand];
   }
   if (command == "paymentRequest.responseComplete") {
     return [self handleResponseComplete:JSONCommand];
@@ -347,7 +364,40 @@
   return YES;
 }
 
-- (BOOL)handleRequestCancel {
+- (BOOL)handleRequestAbort:(const base::DictionaryValue&)message {
+  // TODO(crbug.com/602666): Check that there is already a pending request.
+
+  [_unblockEventQueueTimer invalidate];
+  [_paymentResponseTimeoutTimer invalidate];
+  [_updateEventTimeoutTimer invalidate];
+
+  __weak PaymentRequestManager* weakSelf = self;
+
+  ProceduralBlockWithBool cancellationCallback = ^(BOOL) {
+    PaymentRequestManager* strongSelf = weakSelf;
+    // Early return if the manager has been deallocated.
+    if (!strongSelf)
+      return;
+    [[strongSelf paymentRequestJsManager]
+        resolveAbortPromiseWithCompletionHandler:nil];
+  };
+
+  ProceduralBlock callback = ^{
+    PaymentRequestManager* strongSelf = weakSelf;
+    // Early return if the manager has been deallocated.
+    if (!strongSelf)
+      return;
+    [strongSelf
+        terminateRequestWithErrorMessage:@"The payment request was aborted."
+                                callback:cancellationCallback];
+  };
+
+  [_paymentRequestCoordinator displayErrorWithCallback:callback];
+
+  return YES;
+}
+
+- (BOOL)displayErrorThenCancelRequest {
   // TODO(crbug.com/602666): Check that there is already a pending request.
 
   [_unblockEventQueueTimer invalidate];
@@ -360,7 +410,9 @@
     // Early return if the manager has been deallocated.
     if (!strongSelf)
       return;
-    [strongSelf cancelRequestWithErrorMessage:@"Request canceled."];
+    [strongSelf
+        terminateRequestWithErrorMessage:@"The payment request was canceled."
+                                callback:nil];
   };
 
   [_paymentRequestCoordinator displayErrorWithCallback:callback];
@@ -368,7 +420,7 @@
   return YES;
 }
 
-- (BOOL)handleResponseComplete {
+- (BOOL)doResponseComplete {
   base::DictionaryValue command;
   command.SetString("result", "unknown");
   return [self handleResponseComplete:command];
@@ -443,18 +495,18 @@
   _paymentResponseTimeoutTimer =
       [NSTimer scheduledTimerWithTimeInterval:kTimeoutInterval
                                        target:self
-                                     selector:@selector(handleResponseComplete)
+                                     selector:@selector(doResponseComplete)
                                      userInfo:nil
                                       repeats:NO];
 }
 
 - (void)setUpdateEventTimeoutTimer {
-  _updateEventTimeoutTimer =
-      [NSTimer scheduledTimerWithTimeInterval:kTimeoutInterval
-                                       target:self
-                                     selector:@selector(handleRequestCancel)
-                                     userInfo:nil
-                                      repeats:NO];
+  _updateEventTimeoutTimer = [NSTimer
+      scheduledTimerWithTimeInterval:kTimeoutInterval
+                              target:self
+                            selector:@selector(displayErrorThenCancelRequest)
+                            userInfo:nil
+                             repeats:NO];
 }
 
 - (void)dismissUI {
@@ -483,7 +535,8 @@
 
 - (void)paymentRequestCoordinatorDidCancel:
     (PaymentRequestCoordinator*)coordinator {
-  [self cancelRequestWithErrorMessage:@"Request canceled."];
+  [self terminateRequestWithErrorMessage:@"The payment request was canceled."
+                                callback:nil];
 }
 
 - (void)paymentRequestCoordinator:(PaymentRequestCoordinator*)coordinator
diff --git a/ios/chrome/browser/payments/resources/payment_request_manager.js b/ios/chrome/browser/payments/resources/payment_request_manager.js
index b1a9e6e..88ceba38 100644
--- a/ios/chrome/browser/payments/resources/payment_request_manager.js
+++ b/ios/chrome/browser/payments/resources/payment_request_manager.js
@@ -176,6 +176,13 @@
   __gCrWeb['paymentRequestManager'].requestPromiseResolver = null;
 
   /**
+   * The PromiseResolver object used to resolve or reject the promise returned
+   * by PaymentRequest.prototype.abort, if any.
+   * @type {__gCrWeb.PromiseResolver}
+   */
+  __gCrWeb['paymentRequestManager'].abortPromiseResolver = null;
+
+  /**
    * The PromiseResolver object used to resolve the promise returned by
    * PaymentResponse.prototype.complete, if any.
    * @type {window.PaymentRequest}
@@ -231,7 +238,7 @@
         })
         .catch(function() {
           var message = {
-            'command': 'paymentRequest.requestCancel',
+            'command': 'paymentRequest.requestAbort',
           };
           __gCrWeb.message.invokeOnHost(message);
 
@@ -293,6 +300,20 @@
   };
 
   /**
+   * Resolves the promise returned by calling PaymentRequest.prototype.abort.
+   * This method also gets called when the request is aborted through rejecting
+   * the promise passed to PaymentRequestUpdateEvent.prototype.updateWith.
+   * Therefore, it does nothing if there is no abort promise to resolve.
+   */
+  __gCrWeb['paymentRequestManager'].resolveAbortPromise = function() {
+    if (!__gCrWeb['paymentRequestManager'].abortPromiseResolver)
+      return;
+
+    __gCrWeb['paymentRequestManager'].abortPromiseResolver.resolve();
+    __gCrWeb['paymentRequestManager'].abortPromiseResolver = null;
+  };
+
+  /**
    * Serializes |paymentRequest| to a SerializedPaymentRequest object.
    * @param {window.PaymentRequest} paymentRequest
    * @return {SerializedPaymentRequest}
@@ -513,7 +534,7 @@
 
 /**
  * Presents the PaymentRequest UI to the user.
- * @return {!Promise<window.PaymentResponse>} A promise to notify the caller of
+ * @return {!Promise<window.PaymentResponse>} A promise to notify the caller
  *     whether the user accepted or rejected the request.
  */
 window.PaymentRequest.prototype.show = function() {
@@ -535,6 +556,28 @@
 };
 
 /**
+ * May be called if the web page wishes to tell the user agent to abort the
+ * payment request and to tear down any user interface that might be shown.
+ * @return {!Promise<undefined>} A promise to notify the caller whether the user
+ *     agent was able to abort the payment request.
+ */
+window.PaymentRequest.prototype.abort = function() {
+  if (!__gCrWeb['paymentRequestManager'].pendingRequest) {
+    __gCrWeb['paymentRequestManager'].rejectRequestPromise(
+        'Internal PaymentRequest error: No pending request.');
+  }
+
+  var message = {
+    'command': 'paymentRequest.requestAbort',
+  };
+  __gCrWeb.message.invokeOnHost(message);
+
+  __gCrWeb['paymentRequestManager'].abortPromiseResolver =
+      new __gCrWeb.PromiseResolver();
+  return __gCrWeb['paymentRequestManager'].abortPromiseResolver.promise;
+};
+
+/**
  * @typedef {{
  *   supportedMethods: !Array<string>,
  *   data: (Object|undefined)
diff --git a/ios/chrome/browser/suggestions/OWNERS b/ios/chrome/browser/suggestions/OWNERS
index 8fde2a2..1986f2f0 100644
--- a/ios/chrome/browser/suggestions/OWNERS
+++ b/ios/chrome/browser/suggestions/OWNERS
@@ -1,3 +1,6 @@
 justincohen@chromium.org
 mathp@chromium.org
 rohitrao@chromium.org
+
+# TEAM: ntp-dev@chromium.org
+# COMPONENT: UI>Browser>NewTabPage
diff --git a/ios/web/BUILD.gn b/ios/web/BUILD.gn
index b81d67a..1536e95 100644
--- a/ios/web/BUILD.gn
+++ b/ios/web/BUILD.gn
@@ -411,6 +411,8 @@
     "public/test/fakes/test_web_state.mm",
     "public/test/fakes/test_web_state_delegate.h",
     "public/test/fakes/test_web_state_delegate.mm",
+    "public/test/fakes/test_web_state_observer.h",
+    "public/test/fakes/test_web_state_observer.mm",
     "public/test/fakes/test_web_view_content_view.h",
     "public/test/fakes/test_web_view_content_view.mm",
     "public/test/http_server.h",
diff --git a/ios/web/public/test/fakes/test_web_state_observer.h b/ios/web/public/test/fakes/test_web_state_observer.h
new file mode 100644
index 0000000..f2e5132
--- /dev/null
+++ b/ios/web/public/test/fakes/test_web_state_observer.h
@@ -0,0 +1,74 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_WEB_PUBLIC_TEST_FAKES_TEST_WEB_STATE_OBSERVER_H_
+#define IOS_WEB_PUBLIC_TEST_FAKES_TEST_WEB_STATE_OBSERVER_H_
+
+#include "ios/web/public/web_state/web_state_observer.h"
+
+class GURL;
+
+namespace web {
+
+class WebState;
+
+// Test observer to check that the WebStateObserver methods are called as
+// expected.
+class TestWebStateObserver : public WebStateObserver {
+ public:
+  TestWebStateObserver(WebState* web_state) : WebStateObserver(web_state) {}
+
+  // Methods returning true if the corresponding WebStateObserver method has
+  // been called.
+  bool provisional_navigation_started_called() const {
+    return provisional_navigation_started_called_;
+  };
+  bool navigation_items_pruned_called() const {
+    return navigation_items_pruned_called_;
+  }
+  bool navigation_item_changed_called() const {
+    return navigation_item_changed_called_;
+  }
+  bool navigation_item_committed_called() const {
+    return navigation_item_committed_called_;
+  }
+  bool page_loaded_called_with_success() const {
+    return page_loaded_called_with_success_;
+  }
+  bool history_state_changed_called() const {
+    return history_state_changed_called_;
+  }
+  bool did_finish_navigation_called() const {
+    return did_finish_navigation_called_;
+  }
+  bool title_was_set_called() const { return title_was_set_called_; }
+  bool web_state_destroyed_called() const {
+    return web_state_destroyed_called_;
+  }
+
+ private:
+  // WebStateObserver implementation:
+  void ProvisionalNavigationStarted(const GURL& url) override;
+  void NavigationItemsPruned(size_t pruned_item_count) override;
+  void NavigationItemChanged() override;
+  void NavigationItemCommitted(const LoadCommittedDetails&) override;
+  void DidFinishNavigation(NavigationContext* navigation_context) override;
+  void PageLoaded(PageLoadCompletionStatus load_completion_status) override;
+  void TitleWasSet() override;
+  void WebStateDestroyed() override;
+
+  bool provisional_navigation_started_called_ = false;
+  bool navigation_items_pruned_called_ = false;
+  bool navigation_item_changed_called_ = false;
+  bool navigation_item_committed_called_ = false;
+  bool page_loaded_called_with_success_ = false;
+  bool history_state_changed_called_ = false;
+  bool did_finish_navigation_called_ = false;
+  bool title_was_set_called_ = false;
+  bool web_state_destroyed_called_ = false;
+};
+
+}  // namespace web
+
+#endif  // IOS_WEB_PUBLIC_TEST_FAKES_TEST_WEB_STATE_OBSERVER_H_
diff --git a/ios/web/public/test/fakes/test_web_state_observer.mm b/ios/web/public/test/fakes/test_web_state_observer.mm
new file mode 100644
index 0000000..9f859c5
--- /dev/null
+++ b/ios/web/public/test/fakes/test_web_state_observer.mm
@@ -0,0 +1,48 @@
+// 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 "ios/web/public/test/fakes/test_web_state_observer.h"
+
+#include "ios/web/public/web_state/web_state.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace web {
+
+void TestWebStateObserver::ProvisionalNavigationStarted(const GURL&) {
+  provisional_navigation_started_called_ = true;
+}
+
+void TestWebStateObserver::NavigationItemsPruned(size_t) {
+  navigation_items_pruned_called_ = true;
+}
+
+void TestWebStateObserver::NavigationItemChanged() {
+  navigation_item_changed_called_ = true;
+}
+
+void TestWebStateObserver::NavigationItemCommitted(
+    const LoadCommittedDetails& load_details) {
+  navigation_item_committed_called_ = true;
+}
+
+void TestWebStateObserver::DidFinishNavigation(NavigationContext*) {
+  did_finish_navigation_called_ = true;
+}
+
+void TestWebStateObserver::PageLoaded(PageLoadCompletionStatus status) {
+  page_loaded_called_with_success_ =
+      status == PageLoadCompletionStatus::SUCCESS;
+}
+
+void TestWebStateObserver::TitleWasSet() {
+  title_was_set_called_ = true;
+}
+
+void TestWebStateObserver::WebStateDestroyed() {
+  EXPECT_TRUE(web_state()->IsBeingDestroyed());
+  web_state_destroyed_called_ = true;
+  Observe(nullptr);
+}
+
+}  // namespace web
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm
index d6deb822..5d3d172b 100644
--- a/ios/web/web_state/ui/crw_web_controller.mm
+++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -2133,24 +2133,18 @@
   NSUserDefaults* userDefaults = [NSUserDefaults standardUserDefaults];
   if (![userDefaults boolForKey:@"PendingIndexNavigationDisabled"]) {
     [self clearTransientContentView];
+    [self updateDesktopUserAgentForEntry:toEntry fromEntry:fromEntry];
 
     BOOL sameDocumentNavigation = [sessionController
         isSameDocumentNavigationBetweenItem:fromEntry.navigationItem
                                     andItem:toEntry.navigationItem];
     if (sameDocumentNavigation) {
-      [self.sessionController goToItemAtIndex:index];
-      // TODO(crbug.com/684098): move this call out this block to avoid code
-      // duplication.
-      [self webWillFinishHistoryNavigationFromEntry:fromEntry];
+      [sessionController goToItemAtIndex:index];
       [self updateHTML5HistoryState];
     } else {
       [sessionController discardNonCommittedItems];
       [sessionController setPendingItemIndex:index];
 
-      // TODO(crbug.com/684098): move this call out this block to avoid code
-      // duplication.
-      [self webWillFinishHistoryNavigationFromEntry:fromEntry];
-
       web::NavigationItemImpl* pendingItem =
           sessionController.pendingEntry.navigationItemImpl;
       pendingItem->SetTransitionType(ui::PageTransitionFromInt(
@@ -2159,7 +2153,7 @@
       [self loadCurrentURL];
     }
   } else {
-    [self.sessionController goToItemAtIndex:index];
+    [sessionController goToItemAtIndex:index];
     if (fromEntry)
       [self finishHistoryNavigationFromEntry:fromEntry];
   }
diff --git a/ios/web/web_state/web_state_impl_unittest.mm b/ios/web/web_state/web_state_impl_unittest.mm
index f2253e5..c0a1274 100644
--- a/ios/web/web_state/web_state_impl_unittest.mm
+++ b/ios/web/web_state/web_state_impl_unittest.mm
@@ -18,6 +18,7 @@
 #include "ios/web/public/load_committed_details.h"
 #include "ios/web/public/test/fakes/test_browser_state.h"
 #import "ios/web/public/test/fakes/test_web_state_delegate.h"
+#import "ios/web/public/test/fakes/test_web_state_observer.h"
 #include "ios/web/public/test/web_test.h"
 #import "ios/web/public/web_state/context_menu_params.h"
 #include "ios/web/public/web_state/global_web_state_observer.h"
@@ -114,90 +115,6 @@
   bool web_state_destroyed_called_;
 };
 
-// Test observer to check that the WebStateObserver methods are called as
-// expected.
-class TestWebStateObserver : public WebStateObserver {
- public:
-  TestWebStateObserver(WebState* web_state)
-      : WebStateObserver(web_state),
-        provisional_navigation_started_called_(false),
-        navigation_items_pruned_called_(false),
-        navigation_item_changed_called_(false),
-        navigation_item_committed_called_(false),
-        page_loaded_called_with_success_(false),
-        history_state_changed_called_(false),
-        did_finish_navigation_called_(false),
-        title_was_set_called_(false),
-        web_state_destroyed_called_(false) {}
-
-  // Methods returning true if the corresponding WebStateObserver method has
-  // been called.
-  bool provisional_navigation_started_called() const {
-    return provisional_navigation_started_called_;
-  };
-  bool navigation_items_pruned_called() const {
-    return navigation_items_pruned_called_;
-  }
-  bool navigation_item_changed_called() const {
-    return navigation_item_changed_called_;
-  }
-  bool navigation_item_committed_called() const {
-    return navigation_item_committed_called_;
-  }
-  bool page_loaded_called_with_success() const {
-    return page_loaded_called_with_success_;
-  }
-  bool history_state_changed_called() const {
-    return history_state_changed_called_;
-  }
-  bool did_finish_navigation_called() const {
-    return did_finish_navigation_called_;
-  }
-  bool title_was_set_called() const { return title_was_set_called_; }
-  bool web_state_destroyed_called() const {
-    return web_state_destroyed_called_;
-  }
-
- private:
-  // WebStateObserver implementation:
-  void ProvisionalNavigationStarted(const GURL& url) override {
-    provisional_navigation_started_called_ = true;
-  }
-  void NavigationItemsPruned(size_t pruned_item_count) override {
-    navigation_items_pruned_called_ = true;
-  }
-  void NavigationItemChanged() override {
-    navigation_item_changed_called_ = true;
-  }
-  void NavigationItemCommitted(
-      const LoadCommittedDetails& load_details) override {
-    navigation_item_committed_called_ = true;
-  }
-  void DidFinishNavigation(NavigationContext* navigation_context) override {
-    did_finish_navigation_called_ = true;
-  }
-  void PageLoaded(PageLoadCompletionStatus load_completion_status) override {
-    page_loaded_called_with_success_ =
-        load_completion_status == PageLoadCompletionStatus::SUCCESS;
-  }
-  void TitleWasSet() override { title_was_set_called_ = true; }
-  void WebStateDestroyed() override {
-    EXPECT_TRUE(web_state()->IsBeingDestroyed());
-    web_state_destroyed_called_ = true;
-    Observe(nullptr);
-  }
-
-  bool provisional_navigation_started_called_;
-  bool navigation_items_pruned_called_;
-  bool navigation_item_changed_called_;
-  bool navigation_item_committed_called_;
-  bool page_loaded_called_with_success_;
-  bool history_state_changed_called_;
-  bool did_finish_navigation_called_;
-  bool title_was_set_called_;
-  bool web_state_destroyed_called_;
-};
-
 // Test decider to check that the WebStatePolicyDecider methods are called as
 // expected.
 class MockWebStatePolicyDecider : public WebStatePolicyDecider {
diff --git a/mash/common/BUILD.gn b/mash/common/BUILD.gn
index 44d2bbc..dd20674 100644
--- a/mash/common/BUILD.gn
+++ b/mash/common/BUILD.gn
@@ -15,6 +15,6 @@
   ]
 
   if (use_ash) {
-    deps += [ "//ash/public/interfaces" ]
+    deps += [ "//ash/public/cpp:ash_public_cpp" ]
   }
 }
diff --git a/media/gpu/BUILD.gn b/media/gpu/BUILD.gn
index 3e95bbf..e026eee 100644
--- a/media/gpu/BUILD.gn
+++ b/media/gpu/BUILD.gn
@@ -146,6 +146,7 @@
     "//ui/gfx/geometry",
   ]
   deps = [
+    "//ui/base",
     "//ui/display/types",
     "//ui/gl",
     "//ui/platform_window",
diff --git a/media/gpu/DEPS b/media/gpu/DEPS
index 0f316510..6ce29b6 100644
--- a/media/gpu/DEPS
+++ b/media/gpu/DEPS
@@ -6,6 +6,7 @@
   "+third_party/v4l-utils",
   "+third_party/webrtc/common_video",
   "+third_party/webrtc/system_wrappers",
+  "+ui/base",
   "+ui/display/manager/chromeos",
   "+ui/display/types",
   "+ui/platform_window",
diff --git a/media/gpu/dxva_video_decode_accelerator_win.cc b/media/gpu/dxva_video_decode_accelerator_win.cc
index 003689c8..a77d3d6 100644
--- a/media/gpu/dxva_video_decode_accelerator_win.cc
+++ b/media/gpu/dxva_video_decode_accelerator_win.cc
@@ -24,6 +24,7 @@
 #include "base/base_paths_win.h"
 #include "base/bind.h"
 #include "base/callback.h"
+#include "base/command_line.h"
 #include "base/debug/alias.h"
 #include "base/file_version_info.h"
 #include "base/files/file_path.h"
@@ -49,6 +50,7 @@
 #include "media/video/video_decode_accelerator.h"
 #include "third_party/angle/include/EGL/egl.h"
 #include "third_party/angle/include/EGL/eglext.h"
+#include "ui/base/ui_base_switches.h"
 #include "ui/gfx/color_space_win.h"
 #include "ui/gl/gl_angle_util_win.h"
 #include "ui/gl/gl_bindings.h"
@@ -563,6 +565,13 @@
     use_fp16_ = true;
   }
 
+  // Unfortunately, the profile is currently unreliable for
+  // VP9 (crbug.com/592074) so also try to use fp16 if HDR is on.
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kEnableHDROutput)) {
+    use_fp16_ = true;
+  }
+
   // Not all versions of Windows 7 and later include Media Foundation DLLs.
   // Instead of crashing while delay loading the DLL when calling MFStartup()
   // below, probe whether we can successfully load the DLL now.
@@ -2495,9 +2504,8 @@
   RETURN_AND_NOTIFY_ON_FAILURE(result, "Failed to complete copying surface",
                                PLATFORM_FAILURE, );
 
-  NotifyPictureReady(
-      picture_buffer->id(), input_buffer_id,
-      copy_nv12_textures_ ? picture_buffer->color_space() : gfx::ColorSpace());
+  NotifyPictureReady(picture_buffer->id(), input_buffer_id,
+                     picture_buffer->color_space());
 
   {
     base::AutoLock lock(decoder_lock_);
@@ -2598,6 +2606,11 @@
                                  PLATFORM_FAILURE, );
   }
 
+  OutputBuffers::iterator it = output_picture_buffers_.find(picture_buffer_id);
+  if (it != output_picture_buffers_.end()) {
+    it->second->set_color_space(dx11_converter_output_color_space_);
+  }
+
   // The input to the video processor is the output sample.
   base::win::ScopedComPtr<IMFSample> input_sample_for_conversion;
   {
@@ -2809,27 +2822,34 @@
 
     video_context_->VideoProcessorSetStreamColorSpace(d3d11_processor_.get(), 0,
                                                       &d3d11_color_space);
+    dx11_converter_output_color_space_ = color_space;
   } else {
+    dx11_converter_output_color_space_ = gfx::ColorSpace::CreateSRGB();
     // Not sure if this call is expensive, let's only do it if the color
     // space changes.
-    gfx::ColorSpace output_color_space = gfx::ColorSpace::CreateSRGB();
-    if (use_color_info_ && dx11_converter_color_space_ != color_space) {
+    if ((use_color_info_ || use_fp16_) &&
+        dx11_converter_color_space_ != color_space) {
       base::win::ScopedComPtr<ID3D11VideoContext1> video_context1;
       HRESULT hr = video_context_.QueryInterface(video_context1.Receive());
       if (SUCCEEDED(hr)) {
+        if (use_fp16_ && base::CommandLine::ForCurrentProcess()->HasSwitch(
+                             switches::kEnableHDROutput)) {
+          dx11_converter_output_color_space_ =
+              gfx::ColorSpace::CreateSCRGBLinear();
+        }
         video_context1->VideoProcessorSetStreamColorSpace1(
             d3d11_processor_.get(), 0,
             gfx::ColorSpaceWin::GetDXGIColorSpace(color_space));
         video_context1->VideoProcessorSetOutputColorSpace1(
-            d3d11_processor_.get(),
-            gfx::ColorSpaceWin::GetDXGIColorSpace(output_color_space));
+            d3d11_processor_.get(), gfx::ColorSpaceWin::GetDXGIColorSpace(
+                                        dx11_converter_output_color_space_));
       } else {
         D3D11_VIDEO_PROCESSOR_COLOR_SPACE d3d11_color_space =
             gfx::ColorSpaceWin::GetD3D11ColorSpace(color_space);
         video_context_->VideoProcessorSetStreamColorSpace(
             d3d11_processor_.get(), 0, &d3d11_color_space);
-        d3d11_color_space =
-            gfx::ColorSpaceWin::GetD3D11ColorSpace(output_color_space);
+        d3d11_color_space = gfx::ColorSpaceWin::GetD3D11ColorSpace(
+            dx11_converter_output_color_space_);
         video_context_->VideoProcessorSetOutputColorSpace(
             d3d11_processor_.get(), &d3d11_color_space);
       }
diff --git a/media/gpu/dxva_video_decode_accelerator_win.h b/media/gpu/dxva_video_decode_accelerator_win.h
index a4336fb9..df3ff4d 100644
--- a/media/gpu/dxva_video_decode_accelerator_win.h
+++ b/media/gpu/dxva_video_decode_accelerator_win.h
@@ -538,6 +538,9 @@
   // Color spaced used when initializing the dx11 format converter.
   gfx::ColorSpace dx11_converter_color_space_;
 
+  // Outputs from the dx11 format converter will be in this color space.
+  gfx::ColorSpace dx11_converter_output_color_space_;
+
   // Set to true if we are sharing ANGLE's device.
   bool using_angle_device_;
 
diff --git a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
index 2eab430..3ee5aaeb 100644
--- a/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
+++ b/mojo/public/cpp/bindings/lib/interface_endpoint_client.cc
@@ -10,6 +10,7 @@
 
 #include "base/bind.h"
 #include "base/location.h"
+#include "base/logging.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
 #include "base/single_thread_task_runner.h"
@@ -360,7 +361,16 @@
 
 bool InterfaceEndpointClient::HandleValidatedMessage(Message* message) {
   DCHECK_EQ(handle_.id(), message->interface_id());
-  DCHECK(!encountered_error_);
+
+  if (encountered_error_) {
+    // This message is received after error has been encountered. For associated
+    // interfaces, this means the remote side sends a
+    // PeerAssociatedEndpointClosed event but continues to send more messages
+    // for the same interface. Close the pipe because this shouldn't happen.
+    DVLOG(1) << "A message is received for an interface after it has been "
+             << "disconnected. Closing the pipe.";
+    return false;
+  }
 
   if (message->has_flag(Message::kFlagExpectsResponse)) {
     MessageReceiverWithStatus* responder =
diff --git a/net/http/http_server_properties_manager.cc b/net/http/http_server_properties_manager.cc
index e467f56..0c3fe87 100644
--- a/net/http/http_server_properties_manager.cc
+++ b/net/http/http_server_properties_manager.cc
@@ -26,12 +26,12 @@
 // Time to wait before starting an update the http_server_properties_impl_ cache
 // from preferences. Scheduling another update during this period will be a
 // no-op.
-const int64_t kUpdateCacheDelayMs = 1000;
+constexpr base::TimeDelta kUpdateCacheDelay = base::TimeDelta::FromSeconds(1);
 
 // Time to wait before starting an update the preferences from the
 // http_server_properties_impl_ cache. Scheduling another update during this
 // period will be a no-op.
-const int64_t kUpdatePrefsDelayMs = 60000;
+constexpr base::TimeDelta kUpdatePrefsDelay = base::TimeDelta::FromSeconds(60);
 
 // "version" 0 indicates, http_server_properties doesn't have "version"
 // property.
@@ -76,11 +76,12 @@
     PrefDelegate* pref_delegate,
     scoped_refptr<base::SingleThreadTaskRunner> pref_task_runner,
     scoped_refptr<base::SingleThreadTaskRunner> network_task_runner)
-    : pref_task_runner_(pref_task_runner),
+    : pref_task_runner_(std::move(pref_task_runner)),
       pref_delegate_(pref_delegate),
       setting_prefs_(false),
       is_initialized_(false),
-      network_task_runner_(network_task_runner) {
+      network_task_runner_(std::move(network_task_runner)) {
+  DCHECK(pref_task_runner_->RunsTasksOnCurrentThread());
   DCHECK(pref_delegate_);
   pref_weak_ptr_factory_.reset(
       new base::WeakPtrFactory<HttpServerPropertiesManager>(this));
@@ -366,6 +367,16 @@
   return is_initialized_;
 }
 
+// static
+base::TimeDelta HttpServerPropertiesManager::GetUpdateCacheDelayForTesting() {
+  return kUpdateCacheDelay;
+}
+
+// static
+base::TimeDelta HttpServerPropertiesManager::GetUpdatePrefsDelayForTesting() {
+  return kUpdatePrefsDelay;
+}
+
 //
 // Update the HttpServerPropertiesImpl's cache with data from preferences.
 //
@@ -376,7 +387,7 @@
     return;
 
   pref_cache_update_timer_->Start(
-      FROM_HERE, base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs), this,
+      FROM_HERE, kUpdateCacheDelay, this,
       &HttpServerPropertiesManager::UpdateCacheFromPrefsOnPrefThread);
 }
 
@@ -796,7 +807,7 @@
     return;
 
   network_prefs_update_timer_->Start(
-      FROM_HERE, base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs), this,
+      FROM_HERE, kUpdatePrefsDelay, this,
       &HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread);
 
   // TODO(rtenneti): Delete the following histogram after collecting some data.
diff --git a/net/http/http_server_properties_manager.h b/net/http/http_server_properties_manager.h
index d2e6fc3..5ccc7d52 100644
--- a/net/http/http_server_properties_manager.h
+++ b/net/http/http_server_properties_manager.h
@@ -162,6 +162,9 @@
       size_t max_server_configs_stored_in_properties) override;
   bool IsInitialized() const override;
 
+  static base::TimeDelta GetUpdateCacheDelayForTesting();
+  static base::TimeDelta GetUpdatePrefsDelayForTesting();
+
  protected:
   // The location where ScheduleUpdatePrefsOnNetworkThread was called.
   enum Location {
diff --git a/net/http/http_server_properties_manager_unittest.cc b/net/http/http_server_properties_manager_unittest.cc
index 0b9fb61c..35da22f8 100644
--- a/net/http/http_server_properties_manager_unittest.cc
+++ b/net/http/http_server_properties_manager_unittest.cc
@@ -7,15 +7,16 @@
 #include <memory>
 #include <utility>
 
+#include "base/bind.h"
 #include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
 #include "base/macros.h"
 #include "base/memory/ptr_util.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
+#include "base/memory/ref_counted.h"
 #include "base/single_thread_task_runner.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
+#include "base/test/scoped_mock_time_message_loop_task_runner.h"
 #include "base/test/test_mock_time_task_runner.h"
 #include "base/test/test_simple_task_runner.h"
 #include "base/threading/thread_task_runner_handle.h"
@@ -81,12 +82,16 @@
  public:
   TestingHttpServerPropertiesManager(
       HttpServerPropertiesManager::PrefDelegate* pref_delegate,
-      scoped_refptr<base::SingleThreadTaskRunner> pref_task_runner,
-      scoped_refptr<base::SingleThreadTaskRunner> net_task_runner)
+      scoped_refptr<TestMockTimeTaskRunner> pref_task_runner,
+      scoped_refptr<TestMockTimeTaskRunner> net_task_runner)
       : HttpServerPropertiesManager(pref_delegate,
                                     pref_task_runner,
-                                    net_task_runner) {
-    InitializeOnNetworkThread();
+                                    net_task_runner),
+        pref_task_runner_(std::move(pref_task_runner)),
+        net_task_runner_(std::move(net_task_runner)) {
+    // This call must run in the context of |net_task_runner_|.
+    TestMockTimeTaskRunner::ScopedContext scoped_context(net_task_runner_);
+    HttpServerPropertiesManager::InitializeOnNetworkThread();
   }
 
   ~TestingHttpServerPropertiesManager() override {}
@@ -95,19 +100,23 @@
   using HttpServerPropertiesManager::ScheduleUpdateCacheOnPrefThread;
 
   void UpdateCacheFromPrefsOnUIConcrete() {
+    TestMockTimeTaskRunner::ScopedContext scoped_context(pref_task_runner_);
     HttpServerPropertiesManager::UpdateCacheFromPrefsOnPrefThread();
   }
 
   void UpdatePrefsFromCacheOnNetworkThreadConcrete(
       const base::Closure& callback) {
+    TestMockTimeTaskRunner::ScopedContext scoped_context(net_task_runner_);
     HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(callback);
   }
 
   void ScheduleUpdatePrefsOnNetworkThreadConcrete(Location location) {
+    TestMockTimeTaskRunner::ScopedContext scoped_context(net_task_runner_);
     HttpServerPropertiesManager::ScheduleUpdatePrefsOnNetworkThread(location);
   }
 
-  void ScheduleUpdatePrefsOnNetworkThread() {
+  void ScheduleUpdatePrefsOnNetworkThreadDefault() {
+    TestMockTimeTaskRunner::ScopedContext scoped_context(net_task_runner_);
     // Picked a random Location as caller.
     HttpServerPropertiesManager::ScheduleUpdatePrefsOnNetworkThread(
         DETECTED_CORRUPTED_PREFS);
@@ -132,6 +141,11 @@
                     const base::Closure& completion));
 
  private:
+  // References to the underlying task runners, used to simulate running in
+  // their contexts where required.
+  scoped_refptr<TestMockTimeTaskRunner> pref_task_runner_;
+  scoped_refptr<TestMockTimeTaskRunner> net_task_runner_;
+
   DISALLOW_COPY_AND_ASSIGN(TestingHttpServerPropertiesManager);
 };
 
@@ -143,50 +157,36 @@
 
 class HttpServerPropertiesManagerTest : public testing::TestWithParam<int> {
  protected:
-  HttpServerPropertiesManagerTest()
-      : pref_test_task_runner_(new TestMockTimeTaskRunner()),
-        net_test_task_runner_(new TestMockTimeTaskRunner()) {}
+  HttpServerPropertiesManagerTest() = default;
 
   void SetUp() override {
     one_day_from_now_ = base::Time::Now() + base::TimeDelta::FromDays(1);
     pref_delegate_ = new MockPrefDelegate;
     http_server_props_manager_.reset(
         new StrictMock<TestingHttpServerPropertiesManager>(
-            pref_delegate_, pref_test_task_runner_, net_test_task_runner_));
+            pref_delegate_, pref_test_task_runner_.task_runner(),
+            net_test_task_runner_));
 
     EXPECT_FALSE(http_server_props_manager_->IsInitialized());
     ExpectCacheUpdate();
     EXPECT_FALSE(net_test_task_runner_->HasPendingTask());
-    pref_test_task_runner_->FastForwardUntilNoTasksRemain();
-    // InitializeOnNetworkThread() is called from the test thread, so
-    // PostTaskAndReply() will post back to the test thread.
-    // TODO(xunjieli): Fix this in a follow-up so we can use
-    // |net_test_task_runner_|->RunUntilIdle().
-    base::RunLoop().RunUntilIdle();
+    pref_test_task_runner_->RunUntilIdle();
+    net_test_task_runner_->RunUntilIdle();
     EXPECT_TRUE(http_server_props_manager_->IsInitialized());
     EXPECT_FALSE(net_test_task_runner_->HasPendingTask());
     EXPECT_FALSE(pref_test_task_runner_->HasPendingTask());
   }
 
-  void SetUpWithNonTaskRunner() {
-    pref_delegate_ = new MockPrefDelegate;
-    http_server_props_manager_.reset(
-        new StrictMock<TestingHttpServerPropertiesManager>(
-            pref_delegate_, base::ThreadTaskRunnerHandle::Get(),
-            net_test_task_runner_));
-
-    EXPECT_FALSE(net_test_task_runner_->HasPendingTask());
-    ExpectCacheUpdate();
-    base::RunLoop().RunUntilIdle();
-    EXPECT_TRUE(http_server_props_manager_->IsInitialized());
-  }
-
   void TearDown() override {
     if (http_server_props_manager_.get())
       http_server_props_manager_->ShutdownOnPrefThread();
-    base::RunLoop().RunUntilIdle();
-    pref_test_task_runner_->FastForwardUntilNoTasksRemain();
-    net_test_task_runner_->FastForwardUntilNoTasksRemain();
+    // Run pending non-delayed tasks but don't FastForwardUntilNoTasksRemain()
+    // as some delayed tasks may forever repost (e.g. because impl doesn't use a
+    // mock clock and doesn't see timings as having expired, ref.
+    // HttpServerPropertiesImpl::
+    //     ScheduleBrokenAlternateProtocolMappingsExpiration()).
+    pref_test_task_runner_->RunUntilIdle();
+    net_test_task_runner_->RunUntilIdle();
     http_server_props_manager_.reset();
   }
 
@@ -234,8 +234,16 @@
   std::unique_ptr<TestingHttpServerPropertiesManager>
       http_server_props_manager_;
   base::Time one_day_from_now_;
-  scoped_refptr<TestMockTimeTaskRunner> pref_test_task_runner_;
-  scoped_refptr<TestMockTimeTaskRunner> net_test_task_runner_;
+
+  // Overrides the main thread's message loop with a mock tick clock. Making the
+  // main thread the |pref_test_task_runner_| matches expectations better than
+  // having an independent TestMockTimeTaskRunner and makes tests easier to
+  // write.
+  base::ScopedMockTimeMessageLoopTaskRunner pref_test_task_runner_;
+
+  // Mock the net task runner as well.
+  scoped_refptr<TestMockTimeTaskRunner> net_test_task_runner_ =
+      new TestMockTimeTaskRunner;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesManagerTest);
@@ -655,8 +663,6 @@
 // completed.
 TEST_P(HttpServerPropertiesManagerTest,
        SinglePrefUpdateForTwoSpdyServerCacheChanges) {
-  // Keep this in sync with http_server_properties_manager.cc
-  const int64_t kUpdatePrefsDelayMs = 60000;
   ExpectPrefsUpdate(2);
   ExpectScheduleUpdatePrefsOnNetworkThreadRepeatedly(3);
 
@@ -669,9 +675,10 @@
   // The pref update task should be scheduled to network thread.
   EXPECT_EQ(1u, net_test_task_runner_->GetPendingTaskCount());
 
-  // Move forward the task runner with kUpdatePrefsDelayMs/2.
+  // Move forward the task runner short by 20ms.
   net_test_task_runner_->FastForwardBy(
-      base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs / 2));
+      HttpServerPropertiesManager::GetUpdatePrefsDelayForTesting() -
+      base::TimeDelta::FromMilliseconds(20));
 
   // Set another spdy server to trigger another call to
   // ScheduleUpdatePrefsOnNetworkThread. There should be no new update posted to
@@ -681,9 +688,8 @@
   EXPECT_EQ(1u, net_test_task_runner_->GetPendingTaskCount());
   EXPECT_FALSE(pref_test_task_runner_->HasPendingTask());
 
-  // Forward another kUpdatePrefsDelayMs/2. The pref update should be executed.
-  net_test_task_runner_->FastForwardBy(
-      base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs / 2));
+  // Move forward the extra 20ms. The pref update should be executed.
+  net_test_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(20));
   EXPECT_FALSE(net_test_task_runner_->HasPendingTask());
   EXPECT_TRUE(pref_test_task_runner_->HasPendingTask());
   pref_test_task_runner_->FastForwardUntilNoTasksRemain();
@@ -802,38 +808,50 @@
 TEST_P(HttpServerPropertiesManagerTest, ConfirmAlternativeService) {
   ExpectPrefsUpdate(1);
 
-  url::SchemeHostPort spdy_server_mail("http", "mail.google.com", 80);
-  EXPECT_FALSE(HasAlternativeService(spdy_server_mail));
-  AlternativeService alternative_service(kProtoHTTP2, "mail.google.com", 443);
+  url::SchemeHostPort spdy_server_mail;
+  AlternativeService alternative_service;
 
-  ExpectScheduleUpdatePrefsOnNetworkThread();
-  http_server_props_manager_->SetAlternativeService(
-      spdy_server_mail, alternative_service, one_day_from_now_);
+  {
+    TestMockTimeTaskRunner::ScopedContext scoped_context(net_test_task_runner_);
 
-  EXPECT_FALSE(http_server_props_manager_->IsAlternativeServiceBroken(
-      alternative_service));
-  EXPECT_FALSE(http_server_props_manager_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+    spdy_server_mail = url::SchemeHostPort("http", "mail.google.com", 80);
+    EXPECT_FALSE(HasAlternativeService(spdy_server_mail));
+    alternative_service =
+        AlternativeService(kProtoHTTP2, "mail.google.com", 443);
 
-  ExpectScheduleUpdatePrefsOnNetworkThread();
-  http_server_props_manager_->MarkAlternativeServiceBroken(alternative_service);
-  EXPECT_TRUE(http_server_props_manager_->IsAlternativeServiceBroken(
-      alternative_service));
-  EXPECT_TRUE(http_server_props_manager_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+    ExpectScheduleUpdatePrefsOnNetworkThread();
+    http_server_props_manager_->SetAlternativeService(
+        spdy_server_mail, alternative_service, one_day_from_now_);
 
-  ExpectScheduleUpdatePrefsOnNetworkThread();
-  http_server_props_manager_->ConfirmAlternativeService(alternative_service);
-  EXPECT_FALSE(http_server_props_manager_->IsAlternativeServiceBroken(
-      alternative_service));
-  EXPECT_FALSE(http_server_props_manager_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
-  // ExpectScheduleUpdatePrefsOnNetworkThread() should be called only once.
-  http_server_props_manager_->ConfirmAlternativeService(alternative_service);
-  EXPECT_FALSE(http_server_props_manager_->IsAlternativeServiceBroken(
-      alternative_service));
-  EXPECT_FALSE(http_server_props_manager_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+    EXPECT_FALSE(http_server_props_manager_->IsAlternativeServiceBroken(
+        alternative_service));
+    EXPECT_FALSE(
+        http_server_props_manager_->WasAlternativeServiceRecentlyBroken(
+            alternative_service));
+
+    ExpectScheduleUpdatePrefsOnNetworkThread();
+    http_server_props_manager_->MarkAlternativeServiceBroken(
+        alternative_service);
+    EXPECT_TRUE(http_server_props_manager_->IsAlternativeServiceBroken(
+        alternative_service));
+    EXPECT_TRUE(http_server_props_manager_->WasAlternativeServiceRecentlyBroken(
+        alternative_service));
+
+    ExpectScheduleUpdatePrefsOnNetworkThread();
+    http_server_props_manager_->ConfirmAlternativeService(alternative_service);
+    EXPECT_FALSE(http_server_props_manager_->IsAlternativeServiceBroken(
+        alternative_service));
+    EXPECT_FALSE(
+        http_server_props_manager_->WasAlternativeServiceRecentlyBroken(
+            alternative_service));
+    // ExpectScheduleUpdatePrefsOnNetworkThread() should be called only once.
+    http_server_props_manager_->ConfirmAlternativeService(alternative_service);
+    EXPECT_FALSE(http_server_props_manager_->IsAlternativeServiceBroken(
+        alternative_service));
+    EXPECT_FALSE(
+        http_server_props_manager_->WasAlternativeServiceRecentlyBroken(
+            alternative_service));
+  }
 
   // Run the task.
   EXPECT_FALSE(pref_test_task_runner_->HasPendingTask());
@@ -846,10 +864,14 @@
 
   Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
 
-  EXPECT_FALSE(http_server_props_manager_->IsAlternativeServiceBroken(
-      alternative_service));
-  EXPECT_FALSE(http_server_props_manager_->WasAlternativeServiceRecentlyBroken(
-      alternative_service));
+  {
+    TestMockTimeTaskRunner::ScopedContext scoped_context(net_test_task_runner_);
+    EXPECT_FALSE(http_server_props_manager_->IsAlternativeServiceBroken(
+        alternative_service));
+    EXPECT_FALSE(
+        http_server_props_manager_->WasAlternativeServiceRecentlyBroken(
+            alternative_service));
+  }
 }
 
 TEST_P(HttpServerPropertiesManagerTest, SupportsQuic) {
@@ -939,31 +961,33 @@
 }
 
 TEST_P(HttpServerPropertiesManagerTest, Clear) {
-  // This task expect to run the QuitWhenIdleClosure in the current thread,
-  // thus can not mock the pref task runner.
-  SetUpWithNonTaskRunner();
-
   ExpectPrefsUpdate(1);
   ExpectScheduleUpdatePrefsOnNetworkThreadRepeatedly(5);
 
-  url::SchemeHostPort spdy_server("https", "mail.google.com", 443);
-  http_server_props_manager_->SetSupportsSpdy(spdy_server, true);
-  AlternativeService alternative_service(kProtoHTTP2, "mail.google.com", 1234);
-  http_server_props_manager_->SetAlternativeService(
-      spdy_server, alternative_service, one_day_from_now_);
-  IPAddress actual_address(127, 0, 0, 1);
-  http_server_props_manager_->SetSupportsQuic(true, actual_address);
-  ServerNetworkStats stats;
-  stats.srtt = base::TimeDelta::FromMicroseconds(10);
-  http_server_props_manager_->SetServerNetworkStats(spdy_server, stats);
+  const url::SchemeHostPort spdy_server("https", "mail.google.com", 443);
+  const IPAddress actual_address(127, 0, 0, 1);
+  const QuicServerId mail_quic_server_id("mail.google.com", 80);
+  const std::string quic_server_info1("quic_server_info1");
 
-  QuicServerId mail_quic_server_id("mail.google.com", 80);
-  std::string quic_server_info1("quic_server_info1");
-  http_server_props_manager_->SetQuicServerInfo(mail_quic_server_id,
-                                                quic_server_info1);
+  {
+    TestMockTimeTaskRunner::ScopedContext scoped_context(net_test_task_runner_);
+
+    http_server_props_manager_->SetSupportsSpdy(spdy_server, true);
+    AlternativeService alternative_service(kProtoHTTP2, "mail.google.com",
+                                           1234);
+    http_server_props_manager_->SetAlternativeService(
+        spdy_server, alternative_service, one_day_from_now_);
+    http_server_props_manager_->SetSupportsQuic(true, actual_address);
+    ServerNetworkStats stats;
+    stats.srtt = base::TimeDelta::FromMicroseconds(10);
+    http_server_props_manager_->SetServerNetworkStats(spdy_server, stats);
+
+    http_server_props_manager_->SetQuicServerInfo(mail_quic_server_id,
+                                                  quic_server_info1);
+  }
 
   // Run the task.
-  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(pref_test_task_runner_->HasPendingTask());
   EXPECT_TRUE(net_test_task_runner_->HasPendingTask());
   net_test_task_runner_->FastForwardUntilNoTasksRemain();
   EXPECT_FALSE(net_test_task_runner_->HasPendingTask());
@@ -983,10 +1007,14 @@
 
   ExpectPrefsUpdate(1);
 
-  // Clear http server data, time out if we do not get a completion callback.
-  http_server_props_manager_->Clear(base::MessageLoop::QuitWhenIdleClosure());
-
-  base::RunLoop().Run();
+  // Clear http server data and run the ensuing non-delayed prefs update.
+  {
+    TestMockTimeTaskRunner::ScopedContext scoped_context(net_test_task_runner_);
+    http_server_props_manager_->Clear();
+  }
+  EXPECT_TRUE(pref_test_task_runner_->HasPendingTask());
+  pref_test_task_runner_->RunUntilIdle();
+  EXPECT_FALSE(pref_test_task_runner_->HasPendingTask());
   EXPECT_FALSE(net_test_task_runner_->HasPendingTask());
 
   EXPECT_FALSE(
@@ -1186,8 +1214,6 @@
 
 TEST_P(HttpServerPropertiesManagerTest,
        SingleCacheUpdateForMultipleUpdatesScheduled) {
-  // Keep this in sync with http_server_properties_manager.cc
-  const int64_t kUpdateCacheDelayMs = 1000;
   // Update cache.
   ExpectCacheUpdate();
 
@@ -1196,17 +1222,17 @@
   http_server_props_manager_->ScheduleUpdateCacheOnPrefThread();
   EXPECT_EQ(1u, pref_test_task_runner_->GetPendingTaskCount());
 
-  // Move forward the task runner kUpdateCacheDelayMs/2.
+  // Move forward the task runner short by 20ms.
   pref_test_task_runner_->FastForwardBy(
-      base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs / 2));
+      HttpServerPropertiesManager::GetUpdateCacheDelayForTesting() -
+      base::TimeDelta::FromMilliseconds(20));
   // Schedule a new cache update within the time window should be a no-op.
   http_server_props_manager_->ScheduleUpdateCacheOnPrefThread();
   EXPECT_EQ(1u, pref_test_task_runner_->GetPendingTaskCount());
 
-  // Move forward the task runner kUpdateCaceDelayMs/2, now the cache update
-  // should be exectured.
-  pref_test_task_runner_->FastForwardBy(
-      base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs / 2));
+  // Move forward the task runner the extra 20ms, now the cache update should be
+  // executed.
+  pref_test_task_runner_->FastForwardBy(base::TimeDelta::FromMilliseconds(20));
 
   // Since this test has no pref corruption, there shouldn't be any pref update.
   EXPECT_FALSE(net_test_task_runner_->HasPendingTask());
@@ -1295,44 +1321,56 @@
        DoNotPersistExpiredOrBrokenAlternativeService) {
   ExpectScheduleUpdatePrefsOnNetworkThreadRepeatedly(2);
 
-  AlternativeServiceInfoVector alternative_service_info_vector;
+  {
+    TestMockTimeTaskRunner::ScopedContext scoped_context(net_test_task_runner_);
 
-  const AlternativeService broken_alternative_service(
-      kProtoHTTP2, "broken.example.com", 443);
-  const base::Time time_one_day_later =
-      base::Time::Now() + base::TimeDelta::FromDays(1);
-  alternative_service_info_vector.push_back(
-      AlternativeServiceInfo(broken_alternative_service, time_one_day_later));
-  // #1: MarkAlternativeServiceBroken().
-  http_server_props_manager_->MarkAlternativeServiceBroken(
-      broken_alternative_service);
+    AlternativeServiceInfoVector alternative_service_info_vector;
 
-  const AlternativeService expired_alternative_service(
-      kProtoHTTP2, "expired.example.com", 443);
-  const base::Time time_one_day_ago =
-      base::Time::Now() - base::TimeDelta::FromDays(1);
-  alternative_service_info_vector.push_back(
-      AlternativeServiceInfo(expired_alternative_service, time_one_day_ago));
+    const AlternativeService broken_alternative_service(
+        kProtoHTTP2, "broken.example.com", 443);
+    const base::Time time_one_day_later =
+        base::Time::Now() + base::TimeDelta::FromDays(1);
+    alternative_service_info_vector.push_back(
+        AlternativeServiceInfo(broken_alternative_service, time_one_day_later));
+    // #1: MarkAlternativeServiceBroken().
+    http_server_props_manager_->MarkAlternativeServiceBroken(
+        broken_alternative_service);
 
-  const AlternativeService valid_alternative_service(kProtoHTTP2,
-                                                     "valid.example.com", 443);
-  alternative_service_info_vector.push_back(
-      AlternativeServiceInfo(valid_alternative_service, time_one_day_later));
+    const AlternativeService expired_alternative_service(
+        kProtoHTTP2, "expired.example.com", 443);
+    const base::Time time_one_day_ago =
+        base::Time::Now() - base::TimeDelta::FromDays(1);
+    alternative_service_info_vector.push_back(
+        AlternativeServiceInfo(expired_alternative_service, time_one_day_ago));
 
-  const url::SchemeHostPort server("https", "www.example.com", 443);
-  // #2: SetAlternativeService().
-  ASSERT_TRUE(http_server_props_manager_->SetAlternativeServices(
-      server, alternative_service_info_vector));
+    const AlternativeService valid_alternative_service(
+        kProtoHTTP2, "valid.example.com", 443);
+    alternative_service_info_vector.push_back(
+        AlternativeServiceInfo(valid_alternative_service, time_one_day_later));
+
+    const url::SchemeHostPort server("https", "www.example.com", 443);
+    // #2: SetAlternativeService().
+    ASSERT_TRUE(http_server_props_manager_->SetAlternativeServices(
+        server, alternative_service_info_vector));
+  }
 
   // Update cache.
   ExpectPrefsUpdate(1);
 
   EXPECT_TRUE(net_test_task_runner_->HasPendingTask());
   EXPECT_FALSE(pref_test_task_runner_->HasPendingTask());
-  net_test_task_runner_->FastForwardUntilNoTasksRemain();
+
+  // |net_test_task_runner_| has a remaining pending task to expire
+  // |broken_alternative_service| |time_one_day_later| (and the impl uses
+  // TimeTicks::Now() without a mock clock so FastForwardUntilNoTasksRemain()
+  // would result in an infinite loop).
+  net_test_task_runner_->FastForwardBy(
+      HttpServerPropertiesManager::GetUpdatePrefsDelayForTesting());
+  EXPECT_EQ(1U, net_test_task_runner_->GetPendingTaskCount());
+
   EXPECT_TRUE(pref_test_task_runner_->HasPendingTask());
   pref_test_task_runner_->FastForwardUntilNoTasksRemain();
-  EXPECT_FALSE(net_test_task_runner_->HasPendingTask());
+  EXPECT_EQ(1U, net_test_task_runner_->GetPendingTaskCount());
   EXPECT_FALSE(pref_test_task_runner_->HasPendingTask());
 
   const base::DictionaryValue& pref_dict =
@@ -1457,7 +1495,7 @@
 //
 TEST_P(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs0) {
   // Post an update task to the IO thread.
-  http_server_props_manager_->ScheduleUpdatePrefsOnNetworkThread();
+  http_server_props_manager_->ScheduleUpdatePrefsOnNetworkThreadDefault();
   // Shutdown comes before the task is executed.
   http_server_props_manager_->ShutdownOnPrefThread();
   http_server_props_manager_.reset();
@@ -1472,7 +1510,7 @@
 TEST_P(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs1) {
   ExpectPrefsUpdate(1);
   // Post an update task.
-  http_server_props_manager_->ScheduleUpdatePrefsOnNetworkThread();
+  http_server_props_manager_->ScheduleUpdatePrefsOnNetworkThreadDefault();
   // Shutdown comes before the task is executed.
   http_server_props_manager_->ShutdownOnPrefThread();
   // Run the task after shutdown, but before deletion.
diff --git a/net/socket/ssl_client_socket_impl.cc b/net/socket/ssl_client_socket_impl.cc
index 9315364..a81e331 100644
--- a/net/socket/ssl_client_socket_impl.cc
+++ b/net/socket/ssl_client_socket_impl.cc
@@ -1149,17 +1149,6 @@
 
   SSLContext::GetInstance()->session_cache()->ResetLookupCount(
       GetSessionCacheKey());
-  // If we got a session from the session cache, log how many concurrent
-  // handshakes that session was used in before we finished our handshake. This
-  // is only recorded if the session from the cache was actually used, and only
-  // if the ALPN protocol is h2 (under the assumption that TLS 1.3 servers will
-  // be speaking h2). See https://crbug.com/631988.
-  if (ssl_session_cache_lookup_count_ && negotiated_protocol_ == kProtoHTTP2 &&
-      SSL_session_reused(ssl_.get())) {
-    UMA_HISTOGRAM_EXACT_LINEAR("Net.SSLSessionConcurrentLookupCount",
-                               ssl_session_cache_lookup_count_, 20);
-  }
-
   // Check that if token binding was negotiated, then extended master secret
   // and renegotiation indication must also be negotiated.
   if (tb_was_negotiated_ &&
@@ -1177,6 +1166,17 @@
     negotiated_protocol_ = NextProtoFromString(proto);
   }
 
+  // If we got a session from the session cache, log how many concurrent
+  // handshakes that session was used in before we finished our handshake. This
+  // is only recorded if the session from the cache was actually used, and only
+  // if the ALPN protocol is h2 (under the assumption that TLS 1.3 servers will
+  // be speaking h2). See https://crbug.com/631988.
+  if (ssl_session_cache_lookup_count_ && negotiated_protocol_ == kProtoHTTP2 &&
+      SSL_session_reused(ssl_.get())) {
+    UMA_HISTOGRAM_EXACT_LINEAR("Net.SSLSessionConcurrentLookupCount",
+                               ssl_session_cache_lookup_count_, 20);
+  }
+
   RecordNegotiatedProtocol();
   RecordChannelIDSupport();
 
diff --git a/net/tools/transport_security_state_generator/transport_security_state_generator.cc b/net/tools/transport_security_state_generator/transport_security_state_generator.cc
index 45c528d..4e93a49 100644
--- a/net/tools/transport_security_state_generator/transport_security_state_generator.cc
+++ b/net/tools/transport_security_state_generator/transport_security_state_generator.cc
@@ -546,6 +546,7 @@
       *base::CommandLine::ForCurrentProcess();
 
   logging::LoggingSettings settings;
+  settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
   logging::InitLogging(settings);
 
 #if defined(OS_WIN)
diff --git a/remoting/OWNERS b/remoting/OWNERS
index 7966cd0c..6afa93c 100644
--- a/remoting/OWNERS
+++ b/remoting/OWNERS
@@ -5,3 +5,5 @@
 lambroslambrou@chromium.org
 sergeyu@chromium.org
 wez@chromium.org
+
+# COMPONENT: Services>Chromoting
diff --git a/services/ui/surfaces/display_output_surface.cc b/services/ui/surfaces/display_output_surface.cc
index 37604e7..85ece68d 100644
--- a/services/ui/surfaces/display_output_surface.cc
+++ b/services/ui/surfaces/display_output_surface.cc
@@ -54,17 +54,32 @@
   context_provider()->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0);
 }
 
+void DisplayOutputSurface::SetDrawRectangle(const gfx::Rect& rect) {
+  if (set_draw_rectangle_for_frame_)
+    return;
+  DCHECK(gfx::Rect(size_).Contains(rect));
+  DCHECK(has_set_draw_rectangle_since_last_resize_ ||
+         (gfx::Rect(size_) == rect));
+  set_draw_rectangle_for_frame_ = true;
+  has_set_draw_rectangle_since_last_resize_ = true;
+  context_provider()->ContextGL()->SetDrawRectangleCHROMIUM(
+      rect.x(), rect.y(), rect.width(), rect.height());
+}
+
 void DisplayOutputSurface::Reshape(const gfx::Size& size,
                                    float device_scale_factor,
                                    const gfx::ColorSpace& color_space,
                                    bool has_alpha,
                                    bool use_stencil) {
+  size_ = size;
+  has_set_draw_rectangle_since_last_resize_ = false;
   context_provider()->ContextGL()->ResizeCHROMIUM(
       size.width(), size.height(), device_scale_factor, has_alpha);
 }
 
 void DisplayOutputSurface::SwapBuffers(cc::OutputSurfaceFrame frame) {
   DCHECK(context_provider_);
+  set_draw_rectangle_for_frame_ = false;
   if (frame.sub_buffer_rect) {
     context_provider_->ContextSupport()->PartialSwapBuffers(
         *frame.sub_buffer_rect);
diff --git a/services/ui/surfaces/display_output_surface.h b/services/ui/surfaces/display_output_surface.h
index db654cf..0861c1d7 100644
--- a/services/ui/surfaces/display_output_surface.h
+++ b/services/ui/surfaces/display_output_surface.h
@@ -30,6 +30,7 @@
   void EnsureBackbuffer() override;
   void DiscardBackbuffer() override;
   void BindFramebuffer() override;
+  void SetDrawRectangle(const gfx::Rect& draw_rectangle) override;
   void Reshape(const gfx::Size& size,
                float device_scale_factor,
                const gfx::ColorSpace& color_space,
@@ -61,6 +62,10 @@
 
   cc::OutputSurfaceClient* client_ = nullptr;
   cc::SyntheticBeginFrameSource* const synthetic_begin_frame_source_;
+  bool set_draw_rectangle_for_frame_ = false;
+  // True if the draw rectangle has been set at all since the last resize.
+  bool has_set_draw_rectangle_since_last_resize_ = false;
+  gfx::Size size_;
 
   base::WeakPtrFactory<DisplayOutputSurface> weak_ptr_factory_;
 };
diff --git a/storage/browser/blob/view_blob_internals_job.cc b/storage/browser/blob/view_blob_internals_job.cc
index 095376b3..9d4862a 100644
--- a/storage/browser/blob/view_blob_internals_job.cc
+++ b/storage/browser/blob/view_blob_internals_job.cc
@@ -29,8 +29,10 @@
 #include "storage/browser/blob/blob_storage_context.h"
 #include "storage/browser/blob/blob_storage_registry.h"
 #include "storage/browser/blob/shareable_blob_data_item.h"
+#include "storage/common/blob_storage/blob_storage_constants.h"
 
 namespace {
+using storage::BlobStatus;
 
 const char kEmptyBlobStorageMessage[] = "No available blob data.";
 const char kContentType[] = "Content Type: ";
@@ -45,6 +47,7 @@
 const char kLength[] = "Length: ";
 const char kUUID[] = "Uuid: ";
 const char kRefcount[] = "Refcount: ";
+const char kStatus[] = "Status: ";
 
 void StartHTML(std::string* out) {
   out->append(
@@ -62,6 +65,41 @@
       "</head><body>\n\n");
 }
 
+std::string StatusToString(BlobStatus status) {
+  switch (status) {
+    case BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS:
+      return "BlobStatus::ERR_INVALID_CONSTRUCTION_ARGUMENTS: Illegal blob "
+             "construction.";
+    case BlobStatus::ERR_OUT_OF_MEMORY:
+      return "BlobStatus::ERR_OUT_OF_MEMORY: Not enough memory or disk space "
+             "available for blob.";
+    case BlobStatus::ERR_FILE_WRITE_FAILED:
+      return "BlobStatus::ERR_FILE_WRITE_FAILED: File operation filed";
+    case BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT:
+      return "BlobStatus::ERR_SOURCE_DIED_IN_TRANSIT: Blob source died before "
+             "transporting data to browser.";
+    case BlobStatus::ERR_BLOB_DEREFERENCED_WHILE_BUILDING:
+      return "BlobStatus::ERR_BLOB_DEREFERENCED_WHILE_BUILDING: Blob "
+             "references removed while building.";
+    case BlobStatus::ERR_REFERENCED_BLOB_BROKEN:
+      return "BlobStatus::ERR_REFERENCED_BLOB_BROKEN: Blob contains dependency "
+             "blob that is broken.";
+    case BlobStatus::DONE:
+      return "BlobStatus::DONE: Blob built with no errors.";
+    case BlobStatus::PENDING_QUOTA:
+      return "BlobStatus::PENDING_QUOTA: Blob construction is pending on "
+             "memory or file quota.";
+    case BlobStatus::PENDING_TRANSPORT:
+      return "BlobStatus::PENDING_TRANSPORT: Blob construction is pending on "
+             "data transport from renderer.";
+    case BlobStatus::PENDING_INTERNALS:
+      return "BlobStatus::PENDING_INTERNALS: Blob construction is pending on "
+             "dependency blobs to finish construction.";
+  }
+  NOTREACHED();
+  return "Invalid blob state.";
+}
+
 void EndHTML(std::string* out) {
   out->append("\n</body></html>");
 }
@@ -181,6 +219,7 @@
   StartHTMLList(out);
 
   AddHTMLListItem(kRefcount, base::IntToString(refcount), out);
+  AddHTMLListItem(kStatus, StatusToString(blob_data.status()), out);
   if (!content_type.empty())
     AddHTMLListItem(kContentType, content_type, out);
   if (!content_disposition.empty())
diff --git a/testing/chromoting/OWNERS b/testing/chromoting/OWNERS
index 23fd166..727a384 100644
--- a/testing/chromoting/OWNERS
+++ b/testing/chromoting/OWNERS
@@ -2,3 +2,5 @@
 jamiewalch@chromium.org
 joedow@chromium.org
 sergeyu@chromium.org
+
+# COMPONENT: Services>Chromoting
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 44ed209a..acf2e51 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -403,10 +403,7 @@
             ],
             "experiments": [
                 {
-                    "name": "Expected",
-                    "params": {
-                        "enable_translation": "true"
-                    }
+                    "name": "Expected"
                 }
             ]
         }
@@ -642,6 +639,24 @@
             ]
         }
     ],
+    "DownloadAttributionPerformanceTest": [
+        {
+            "platforms": [
+                "chromeos",
+                "linux",
+                "mac",
+                "win"
+            ],
+            "experiments": [
+                {
+                    "name": "DownloadAttributionEnabled",
+                    "enable_features": [
+                        "DownloadAttribution"
+                    ]
+                }
+            ]
+        }
+    ],
     "DownloadsUi": [
         {
             "platforms": [
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-createElement-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-createElement-expected.txt
deleted file mode 100644
index a4ac3e8..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-createElement-expected.txt
+++ /dev/null
@@ -1,151 +0,0 @@
-This is a testharness.js-based test.
-Found 147 tests; 144 PASS, 3 FAIL, 0 TIMEOUT, 0 NOTRUN.
-PASS createElement(undefined) in HTML document 
-PASS createElement(undefined) in XML document 
-PASS createElement(undefined) in XHTML document 
-PASS createElement(null) in HTML document 
-PASS createElement(null) in XML document 
-PASS createElement(null) in XHTML document 
-PASS createElement("foo") in HTML document 
-PASS createElement("foo") in XML document 
-PASS createElement("foo") in XHTML document 
-PASS createElement("f1oo") in HTML document 
-PASS createElement("f1oo") in XML document 
-PASS createElement("f1oo") in XHTML document 
-PASS createElement("foo1") in HTML document 
-PASS createElement("foo1") in XML document 
-PASS createElement("foo1") in XHTML document 
-PASS createElement("fெ") in HTML document 
-PASS createElement("fெ") in XML document 
-PASS createElement("fெ") in XHTML document 
-PASS createElement("fooெ") in HTML document 
-PASS createElement("fooெ") in XML document 
-PASS createElement("fooெ") in XHTML document 
-PASS createElement(":") in HTML document 
-PASS createElement(":") in XML document 
-PASS createElement(":") in XHTML document 
-PASS createElement(":foo") in HTML document 
-PASS createElement(":foo") in XML document 
-PASS createElement(":foo") in XHTML document 
-PASS createElement("f:oo") in HTML document 
-PASS createElement("f:oo") in XML document 
-PASS createElement("f:oo") in XHTML document 
-PASS createElement("foo:") in HTML document 
-PASS createElement("foo:") in XML document 
-PASS createElement("foo:") in XHTML document 
-PASS createElement("f:o:o") in HTML document 
-PASS createElement("f:o:o") in XML document 
-PASS createElement("f:o:o") in XHTML document 
-PASS createElement("f::oo") in HTML document 
-PASS createElement("f::oo") in XML document 
-PASS createElement("f::oo") in XHTML document 
-PASS createElement("f::oo:") in HTML document 
-PASS createElement("f::oo:") in XML document 
-PASS createElement("f::oo:") in XHTML document 
-PASS createElement("foo:0") in HTML document 
-PASS createElement("foo:0") in XML document 
-PASS createElement("foo:0") in XHTML document 
-PASS createElement("foo:_") in HTML document 
-PASS createElement("foo:_") in XML document 
-PASS createElement("foo:_") in XHTML document 
-PASS createElement("foo:ெ") in HTML document 
-PASS createElement("foo:ெ") in XML document 
-PASS createElement("foo:ெ") in XHTML document 
-PASS createElement("foo:fooெ") in HTML document 
-PASS createElement("foo:fooெ") in XML document 
-PASS createElement("foo:fooெ") in XHTML document 
-PASS createElement("fooெ:foo") in HTML document 
-PASS createElement("fooெ:foo") in XML document 
-PASS createElement("fooெ:foo") in XHTML document 
-PASS createElement("xml") in HTML document 
-PASS createElement("xml") in XML document 
-PASS createElement("xml") in XHTML document 
-PASS createElement("xmlns") in HTML document 
-PASS createElement("xmlns") in XML document 
-PASS createElement("xmlns") in XHTML document 
-PASS createElement("xmlfoo") in HTML document 
-PASS createElement("xmlfoo") in XML document 
-PASS createElement("xmlfoo") in XHTML document 
-PASS createElement("xml:foo") in HTML document 
-PASS createElement("xml:foo") in XML document 
-PASS createElement("xml:foo") in XHTML document 
-PASS createElement("xmlns:foo") in HTML document 
-PASS createElement("xmlns:foo") in XML document 
-PASS createElement("xmlns:foo") in XHTML document 
-PASS createElement("xmlfoo:bar") in HTML document 
-PASS createElement("xmlfoo:bar") in XML document 
-PASS createElement("xmlfoo:bar") in XHTML document 
-PASS createElement("svg") in HTML document 
-PASS createElement("svg") in XML document 
-PASS createElement("svg") in XHTML document 
-PASS createElement("math") in HTML document 
-PASS createElement("math") in XML document 
-PASS createElement("math") in XHTML document 
-PASS createElement("FOO") in HTML document 
-PASS createElement("FOO") in XML document 
-PASS createElement("FOO") in XHTML document 
-FAIL createElement("marK") in HTML document assert_equals: localName expected "marK" but got "mark"
-PASS createElement("marK") in XML document 
-PASS createElement("marK") in XHTML document 
-FAIL createElement("İnput") in HTML document assert_equals: localName expected "İnput" but got "i̇nput"
-PASS createElement("İnput") in XML document 
-PASS createElement("İnput") in XHTML document 
-FAIL createElement("ınput") in HTML document assert_equals: tagName expected "ıNPUT" but got "INPUT"
-PASS createElement("ınput") in XML document 
-PASS createElement("ınput") in XHTML document 
-PASS createElement("") in HTML document 
-PASS createElement("") in XML document 
-PASS createElement("") in XHTML document 
-PASS createElement("1foo") in HTML document 
-PASS createElement("1foo") in XML document 
-PASS createElement("1foo") in XHTML document 
-PASS createElement("1:foo") in HTML document 
-PASS createElement("1:foo") in XML document 
-PASS createElement("1:foo") in XHTML document 
-PASS createElement("fo o") in HTML document 
-PASS createElement("fo o") in XML document 
-PASS createElement("fo o") in XHTML document 
-PASS createElement("ெfoo") in HTML document 
-PASS createElement("ெfoo") in XML document 
-PASS createElement("ெfoo") in XHTML document 
-PASS createElement("}foo") in HTML document 
-PASS createElement("}foo") in XML document 
-PASS createElement("}foo") in XHTML document 
-PASS createElement("f}oo") in HTML document 
-PASS createElement("f}oo") in XML document 
-PASS createElement("f}oo") in XHTML document 
-PASS createElement("foo}") in HTML document 
-PASS createElement("foo}") in XML document 
-PASS createElement("foo}") in XHTML document 
-PASS createElement("\ufffffoo") in HTML document 
-PASS createElement("\ufffffoo") in XML document 
-PASS createElement("\ufffffoo") in XHTML document 
-PASS createElement("f\uffffoo") in HTML document 
-PASS createElement("f\uffffoo") in XML document 
-PASS createElement("f\uffffoo") in XHTML document 
-PASS createElement("foo\uffff") in HTML document 
-PASS createElement("foo\uffff") in XML document 
-PASS createElement("foo\uffff") in XHTML document 
-PASS createElement("<foo") in HTML document 
-PASS createElement("<foo") in XML document 
-PASS createElement("<foo") in XHTML document 
-PASS createElement("foo>") in HTML document 
-PASS createElement("foo>") in XML document 
-PASS createElement("foo>") in XHTML document 
-PASS createElement("<foo>") in HTML document 
-PASS createElement("<foo>") in XML document 
-PASS createElement("<foo>") in XHTML document 
-PASS createElement("f<oo") in HTML document 
-PASS createElement("f<oo") in XML document 
-PASS createElement("f<oo") in XHTML document 
-PASS createElement("-foo") in HTML document 
-PASS createElement("-foo") in XML document 
-PASS createElement("-foo") in XHTML document 
-PASS createElement(".foo") in HTML document 
-PASS createElement(".foo") in XML document 
-PASS createElement(".foo") in XHTML document 
-PASS createElement("ெ") in HTML document 
-PASS createElement("ெ") in XML document 
-PASS createElement("ெ") in XHTML document 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-getElementsByTagName-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-getElementsByTagName-expected.txt
index 2ae7d59..1e242ea 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-getElementsByTagName-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Document-getElementsByTagName-expected.txt
@@ -14,7 +14,7 @@
 PASS Element in non-HTML namespace, no prefix, uppercase name 
 FAIL Element in non-HTML namespace, prefix, lowercase name assert_array_equals: lengths differ, expected 0 got 1
 FAIL Element in non-HTML namespace, prefix, uppercase name assert_array_equals: lengths differ, expected 0 got 1
-FAIL Element in HTML namespace, no prefix, non-ascii characters in name assert_equals: expected "aÇ" but got "aç"
+FAIL Element in HTML namespace, no prefix, non-ascii characters in name assert_array_equals: All uppercase input lengths differ, expected 1 got 0
 PASS Element in non-HTML namespace, non-ascii characters in name 
 FAIL Element in HTML namespace, prefix, non-ascii characters in name assert_array_equals: All uppercase input lengths differ, expected 1 got 0
 FAIL Element in non-HTML namespace, prefix, non-ascii characters in name assert_array_equals: All uppercase input lengths differ, expected 1 got 0
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Element-getElementsByTagName-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Element-getElementsByTagName-expected.txt
index f6061e0..9613941 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Element-getElementsByTagName-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/Element-getElementsByTagName-expected.txt
@@ -14,7 +14,7 @@
 PASS Element in non-HTML namespace, no prefix, uppercase name 
 FAIL Element in non-HTML namespace, prefix, lowercase name assert_array_equals: lengths differ, expected 0 got 1
 FAIL Element in non-HTML namespace, prefix, uppercase name assert_array_equals: lengths differ, expected 0 got 1
-FAIL Element in HTML namespace, no prefix, non-ascii characters in name assert_equals: expected "aÇ" but got "aç"
+FAIL Element in HTML namespace, no prefix, non-ascii characters in name assert_array_equals: All uppercase input lengths differ, expected 1 got 0
 PASS Element in non-HTML namespace, non-ascii characters in name 
 FAIL Element in HTML namespace, prefix, non-ascii characters in name assert_array_equals: All uppercase input lengths differ, expected 1 got 0
 FAIL Element in non-HTML namespace, prefix, non-ascii characters in name assert_array_equals: All uppercase input lengths differ, expected 1 got 0
diff --git a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/case-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/case-expected.txt
index f7c3b788..9da6918 100644
--- a/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/case-expected.txt
+++ b/third_party/WebKit/LayoutTests/external/wpt/dom/nodes/case-expected.txt
@@ -1,5 +1,5 @@
 This is a testharness.js-based test.
-Found 285 tests; 277 PASS, 8 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 285 tests; 278 PASS, 7 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS createElement abc 
 PASS setAttribute abc 
 PASS getAttribute abc 
@@ -20,7 +20,7 @@
 PASS getAttribute ä 
 FAIL getElementsByTagName a:ä assert_array_equals: lengths differ, expected 0 got 3
 PASS getElementsByTagName ä 
-FAIL createElement Ä assert_equals: expected "Ä" but got "ä"
+PASS createElement Ä 
 FAIL setAttribute Ä assert_equals: expected "Ä" but got "ä"
 PASS getAttribute Ä 
 FAIL getElementsByTagName a:Ä assert_array_equals: lengths differ, expected 0 got 3
diff --git a/third_party/WebKit/LayoutTests/external/wpt/storage/opaque-origin.https-expected.txt b/third_party/WebKit/LayoutTests/external/wpt/storage/opaque-origin.https-expected.txt
deleted file mode 100644
index ad133a80..0000000
--- a/third_party/WebKit/LayoutTests/external/wpt/storage/opaque-origin.https-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-This is a testharness.js-based test.
-PASS navigator.storage.persist() in non-sandboxed iframe should not reject 
-FAIL navigator.storage.persist() in sandboxed iframe should reject with TypeError assert_equals: navigator.storage.persist() should reject with TypeError expected "TypeError" but got "NotSupportedError"
-PASS navigator.storage.persisted() in non-sandboxed iframe should not reject 
-FAIL navigator.storage.persisted() in sandboxed iframe should reject with TypeError assert_equals: navigator.storage.persisted() should reject with TypeError expected "TypeError" but got "no rejection"
-PASS navigator.storage.estimate() in non-sandboxed iframe should not reject 
-FAIL navigator.storage.estimate() in sandboxed iframe should reject with TypeError assert_equals: navigator.storage.estimate() should reject with TypeError expected "TypeError" but got "NotSupportedError"
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/fast/harness/perftests/measure-frame-time.html b/third_party/WebKit/LayoutTests/fast/harness/perftests/measure-frame-time.html
index ab1d8a77..7f8479b8 100644
--- a/third_party/WebKit/LayoutTests/fast/harness/perftests/measure-frame-time.html
+++ b/third_party/WebKit/LayoutTests/fast/harness/perftests/measure-frame-time.html
@@ -1,5 +1,9 @@
 <script src="../../../../PerformanceTests/resources/runner.js"></script>
 <script>
+// Suppress JavaScript trace event console messages.
+console.time = function() {};
+console.timeEnd = function() {};
+
 // The initial value doesn't affect result.
 var virtualTime = 123456;
 PerfTestRunner.now = function () { return virtualTime; }
diff --git a/third_party/WebKit/LayoutTests/fast/harness/perftests/measure-time.html b/third_party/WebKit/LayoutTests/fast/harness/perftests/measure-time.html
index a731f482..abfbfff 100644
--- a/third_party/WebKit/LayoutTests/fast/harness/perftests/measure-time.html
+++ b/third_party/WebKit/LayoutTests/fast/harness/perftests/measure-time.html
@@ -1,5 +1,9 @@
 <script src="../../../../PerformanceTests/resources/runner.js"></script>
 <script>
+// Suppress JavaScript trace event console messages.
+console.time = function() {};
+console.timeEnd = function() {};
+
 // The initial value doesn't affect result.
 var virtualTime = 123456;
 PerfTestRunner.now = function () { return virtualTime; }
diff --git a/third_party/WebKit/LayoutTests/fast/harness/perftests/runs-per-second-iterations.html b/third_party/WebKit/LayoutTests/fast/harness/perftests/runs-per-second-iterations.html
index 6560aa9b..78b80b2 100644
--- a/third_party/WebKit/LayoutTests/fast/harness/perftests/runs-per-second-iterations.html
+++ b/third_party/WebKit/LayoutTests/fast/harness/perftests/runs-per-second-iterations.html
@@ -9,6 +9,10 @@
 
 description("This test verifies PerfTestRunner.runPerSecond() calls runFunction as many times as expected.");
 
+// Suppress JavaScript trace event console messages.
+console.time = function() {};
+console.timeEnd = function() {};
+
 var iteration = 0;
 var currentTime = 100;
 var callsInIterations = [];
diff --git a/third_party/WebKit/LayoutTests/fast/harness/perftests/runs-per-second-log.html b/third_party/WebKit/LayoutTests/fast/harness/perftests/runs-per-second-log.html
index dfe63a4..bae16a8b 100644
--- a/third_party/WebKit/LayoutTests/fast/harness/perftests/runs-per-second-log.html
+++ b/third_party/WebKit/LayoutTests/fast/harness/perftests/runs-per-second-log.html
@@ -6,6 +6,10 @@
 <script src="../../../../PerformanceTests/resources/runner.js"></script>
 <script type="text/javascript">
 
+// Suppress JavaScript trace event console messages.
+console.time = function() {};
+console.timeEnd = function() {};
+
 var logLines = [];
 var initial = true;
 var runs = 0;
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js
index 441e3b6..0e78e0f9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/inspector-test.js
@@ -978,7 +978,7 @@
         InspectorTest.animationModel = target.animationModel;
         InspectorTest.serviceWorkerCacheModel = target.serviceWorkerCacheModel;
         InspectorTest.serviceWorkerManager = target.model(SDK.ServiceWorkerManager);
-        InspectorTest.tracingManager = target.tracingManager;
+        InspectorTest.tracingManager = target.model(SDK.TracingManager);
         InspectorTest.mainTarget = target;
     },
 
diff --git a/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js b/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js
index 4013afd..9dff8b17 100644
--- a/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js
+++ b/third_party/WebKit/LayoutTests/http/tests/inspector/timeline-test.js
@@ -134,7 +134,7 @@
 {
     var performanceModel = new Timeline.PerformanceModel();
     UI.panels.timeline._pendingPerformanceModel = performanceModel;
-    return new Timeline.TimelineController(SDK.targetManager.mainTarget(), performanceModel, UI.panels.timeline);
+    return new Timeline.TimelineController(InspectorTest.tracingManager, performanceModel, UI.panels.timeline);
 }
 
 InspectorTest.runWhenTimelineIsReady = function(callback)
@@ -364,7 +364,7 @@
 }
 
 InspectorTest.dumpTimelineFlameChart = function(includeGroups) {
-    const provider = UI.panels.timeline._flameChart._dataProvider;
+    const provider = UI.panels.timeline._flameChart._mainDataProvider;
     InspectorTest.addResult('Timeline Flame Chart');
     InspectorTest.dumpFlameChartProvider(provider, includeGroups);
 }
diff --git a/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/durable-storage-on-insecure-origin.html b/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/durable-storage-on-insecure-origin.html
index 95b792d..00f58d9 100644
--- a/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/durable-storage-on-insecure-origin.html
+++ b/third_party/WebKit/LayoutTests/http/tests/security/powerfulFeatureRestrictions/durable-storage-on-insecure-origin.html
@@ -5,10 +5,11 @@
 <script src="/resources/get-host-info.js"></script>
 <script>
 if (window.location.origin != get_host_info().UNAUTHENTICATED_ORIGIN) {
-    window.location = get_host_info().UNAUTHENTICATED_ORIGIN + window.location.pathname;
+  window.location = get_host_info().UNAUTHENTICATED_ORIGIN + window.location.pathname;
 } else {
-    promise_test(function(test) {
-        return promise_rejects(test, 'SecurityError', navigator.storage.persist());
-    }, "Requires secure context");
+  test(function(test) {
+    assert_false('storage' in navigator,
+                 'navigator.storage attribute has [SecureContext]');
+  }, 'Requires secure context');
 }
 </script>
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-dirxml-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-dirxml-expected.txt
index 1598400..e8304b3 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-dirxml-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-dirxml-expected.txt
@@ -9,5 +9,5 @@
 console-dirxml.html:13 #document-fragment
 console-dirxml.html:14 <p></p>
 console-dirxml.html:15 [p]
-console-dirxml.html:16 [document, document-fragment, span]
+console-dirxml.html:16 (3) [document, document-fragment, span]
 
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 17947fe..e15eb60 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
@@ -18,29 +18,29 @@
 [undefined × 1]
 console-format-array-prototype.html:4 [undefined × 1]
 a2
-[undefined × 5]
-console-format-array-prototype.html:4 [undefined × 5]
+(5) [undefined × 5]
+console-format-array-prototype.html:4 (5) [undefined × 5]
 a3
-[undefined × 1, 2, 3]
-console-format-array-prototype.html:4 [undefined × 1, 2, 3]
+(3) [undefined × 1, 2, 3]
+console-format-array-prototype.html:4 (3) [undefined × 1, 2, 3]
 a4
-[undefined × 15]
-console-format-array-prototype.html:4 [undefined × 15]
+(15) [undefined × 15]
+console-format-array-prototype.html:4 (15) [undefined × 15]
 a5
-[undefined × 8, 8, undefined × 6]
-console-format-array-prototype.html:4 [undefined × 8, 8, undefined × 6]
+(15) [undefined × 8, 8, undefined × 6]
+console-format-array-prototype.html:4 (15) [undefined × 8, 8, undefined × 6]
 a6
-[0, undefined × 9, 10, undefined × 4]
-console-format-array-prototype.html:4 [0, undefined × 9, 10, undefined × 4]
+(15) [0, undefined × 9, 10, undefined × 4]
+console-format-array-prototype.html:4 (15) [0, undefined × 9, 10, undefined × 4]
 a7
-[3: 4, index0: 0, index1: 1, index2: 2, index3: 3, index4: 4…]
-console-format-array-prototype.html:4 [3: 4, index0: 0, index1: 1, index2: 2, index3: 3, index4: 4…]
+(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…]
 a8
-[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
-console-format-array-prototype.html:4 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+(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
-[undefined × 1, 1, 2, 3, 4, undefined × 1, 6, 7, 8, 9, undefined × 1, foo: "bar"]
-console-format-array-prototype.html:4 [undefined × 1, 1, 2, 3, 4, undefined × 1, 6, 7, 8, 9, undefined × 1, foo: "bar"]
+(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"]
 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 0051e91..7ce698e 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
@@ -55,17 +55,17 @@
 console-format-collections.html:65 ArrayLike
 console-format-collections.html:66 ArrayLike
 console-format-collections.html:15 [select#sel, sel: select#sel]
-console-format-collections.html:19 [script, script, script]
-console-format-collections.html:23 [option, option, selectedIndex: 0]
-console-format-collections.html:27 [html, head, script, script, script, body, p, div.c1.c2.c3, form#f, select#sel, option, option, input, input, f: form#f, sel: select#sel, x: NodeList(2)]
-console-format-collections.html:31 [select#sel, input, input, sel: select#sel, x: RadioNodeList(2)]
-console-format-collections.html:35 [input, input, value: ""]
-console-format-collections.html:41 [1, Array(2)]
+console-format-collections.html:19 (3) [script, script, script]
+console-format-collections.html:23 (2) [option, option, selectedIndex: 0]
+console-format-collections.html:27 (14) [html, head, script, script, script, body, p, div.c1.c2.c3, form#f, select#sel, option, option, input, input, f: form#f, sel: select#sel, x: NodeList(2)]
+console-format-collections.html:31 (3) [select#sel, input, input, sel: select#sel, x: RadioNodeList(2)]
+console-format-collections.html:35 (2) [input, input, value: ""]
+console-format-collections.html:41 (2) [1, Array(2)]
 console-format-collections.html:44 NonArrayWithLength {keys: Array(0)}
-console-format-collections.html:51 [1, "2", callee: function, Symbol(Symbol.iterator): function]
-console-format-collections.html:55 ["c1", "c2", "c3", value: "c1 c2 c3"]
-console-format-collections.html:58 [undefined × 5]
-console-format-collections.html:59 [undefined × 4294967295]
+console-format-collections.html:51 (2) [1, "2", callee: function, Symbol(Symbol.iterator): function]
+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: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-format-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-format-expected.txt
index 50cacdc..6352739 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-format-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-format-expected.txt
@@ -212,10 +212,10 @@
 console-format.html:8 [-Infinity]
 globals[20]
 -Infinity
-console-format.html:7 ["test", "test2", undefined × 2, "test4", undefined × 5, foo: Object]
+console-format.html:7 (10) ["test", "test2", undefined × 2, "test4", undefined × 5, foo: Object]
 console-format.html:8 [Array(10)]
 globals[21]
-["test", "test2", undefined × 2, "test4", undefined × 5, foo: Object]
+(10) ["test", "test2", undefined × 2, "test4", undefined × 5, foo: Object]
 console-format.html:7 Object {}
 console-format.html:8 [Object]
 globals[22]
@@ -279,10 +279,10 @@
 console-format.html:8 [DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of th…]
 globals[36]
 DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
-console-format.html:7 Uint8Array(1) [3]
+console-format.html:7 Uint8Array [3]
 console-format.html:8 [Uint8Array(1)]
 globals[37]
-Uint8Array(1) [3]
+Uint8Array [3]
 console-format.html:7 Uint8Array(400) [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…]
 console-format.html:8 [Uint8Array(400)]
 globals[38]
@@ -295,10 +295,10 @@
 console-format.html:8 [n…e.l…e.x.className]
 globals[40]
 namespace.longSubNamespace.x.className {}
-console-format.html:7 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…]
+console-format.html:7 (200) [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…]
 console-format.html:8 [Array(200)]
 globals[41]
-[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…]
+(200) [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…]
 console-format.html:7 ["test"]
 console-format.html:8 [Array(1)]
 globals[42]
@@ -500,7 +500,7 @@
     __proto__: Array(0)
 globals[20]
 -Infinity
-console-format.html:7 ["test", "test2", undefined × 2, "test4", undefined × 5, foo: Object]
+console-format.html:7 (10) ["test", "test2", undefined × 2, "test4", undefined × 5, foo: Object]
     0: "test"
     1: "test2"
     4: "test4"
@@ -512,7 +512,7 @@
     length: 1
     __proto__: Array(0)
 globals[21]
-["test", "test2", undefined × 2, "test4", undefined × 5, foo: Object]
+(10) ["test", "test2", undefined × 2, "test4", undefined × 5, foo: Object]
     0: "test"
     1: "test2"
     4: "test4"
@@ -719,7 +719,7 @@
     __proto__: Array(0)
 globals[36]
 DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.
-console-format.html:7 Uint8Array(1) [3]
+console-format.html:7 Uint8Array [3]
     0: 3
     buffer: (...)
     byteLength: (...)
@@ -732,7 +732,7 @@
     length: 1
     __proto__: Array(0)
 globals[37]
-Uint8Array(1) [3]
+Uint8Array [3]
     0: 3
     buffer: (...)
     byteLength: (...)
@@ -785,7 +785,7 @@
 globals[40]
 namespace.longSubNamespace.x.className {}
     __proto__: Object
-console-format.html:7 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…]
+console-format.html:7 (200) [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…]
     [0 … 99]
     [100 … 199]
     length: 200
@@ -795,7 +795,7 @@
     length: 1
     __proto__: Array(0)
 globals[41]
-[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…]
+(200) [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…]
     [0 … 99]
     [100 … 199]
     length: 200
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 507e64b6..ed814bb 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 Object {}
-console-log-object-with-getter.html:26 [(...), undefined × 1]
+console-log-object-with-getter.html:26 (2) [(...), undefined × 1]
 console-log-object-with-getter.html:27 Object {}
-console-log-object-with-getter.html:25 Object {}foo: Objecta: 1b: 2__proto__: Objectget foo: function ()set bar: function (x)__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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-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 [(...), undefined × 1]0: 1length: 2get 0: function ()set 1: function (x)__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > 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-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 Object {}error: [Exception: Error: myError]function: [Exception: function ()]number: [Exception: 123]string: [Exception: "myString"]get error: function error()get function: function function()get number: function number()get string: function string()__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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-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
+console-log-object-with-getter.html:25 Object {}foo: Objecta: 1b: 2__proto__: Objectget foo: function ()set bar: function (x)__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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-description > 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: function ()set 1: function (x)__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > 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-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 Object {}error: [Exception: Error: myError]function: [Exception: function ()]number: [Exception: 123]string: [Exception: "myString"]get error: function error()get function: function function()get number: function number()get string: function string()__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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-description > 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 5ef1fff..1086024 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
@@ -32,66 +32,66 @@
 Tests that console produces instant previews for arrays and objects.
 
 console-object-preview.html:9 Mutating object in a loop console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:13 Object {a: 0, b: 0, c: 0} console-message > source-code > console-message-anchor > devtools-link > 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 > name > object-value-number > name > object-value-number > name > object-value-number > object-state-note info-note > children
-console-object-preview.html:13 Object {a: 0, b: 0, c: 1} console-message > source-code > console-message-anchor > devtools-link > 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 > name > object-value-number > name > object-value-number > name > object-value-number > object-state-note info-note > children
-console-object-preview.html:13 Object {a: 0, b: 0, c: 2} console-message > source-code > console-message-anchor > devtools-link > 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 > name > object-value-number > name > object-value-number > name > object-value-number > object-state-note info-note > children
+console-object-preview.html:13 Object {a: 0, b: 0, c: 0} console-message > source-code > console-message-anchor > devtools-link > 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-description > name > object-value-number > name > object-value-number > name > object-value-number > object-state-note info-note > children
+console-object-preview.html:13 Object {a: 0, b: 0, c: 1} console-message > source-code > console-message-anchor > devtools-link > 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-description > name > object-value-number > name > object-value-number > name > object-value-number > object-state-note info-note > children
+console-object-preview.html:13 Object {a: 0, b: 0, c: 2} console-message > source-code > console-message-anchor > devtools-link > 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-description > name > object-value-number > name > object-value-number > name > object-value-number > object-state-note info-note > children
 console-object-preview.html:16 Mutating array in a loop console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:20 [0, 0, 0] console-message > source-code > console-message-anchor > devtools-link > 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-value-number > object-value-number > object-value-number > object-state-note info-note > children
-console-object-preview.html:20 [0, 0, 1] console-message > source-code > console-message-anchor > devtools-link > 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-value-number > object-value-number > object-value-number > object-state-note info-note > children
-console-object-preview.html:20 [0, 0, 2] console-message > source-code > console-message-anchor > devtools-link > 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-value-number > object-value-number > object-value-number > object-state-note info-note > children
+console-object-preview.html:20 (3) [0, 0, 0] console-message > source-code > console-message-anchor > devtools-link > 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-value-number > object-value-number > object-value-number > object-state-note info-note > children
+console-object-preview.html:20 (3) [0, 0, 1] console-message > source-code > console-message-anchor > devtools-link > 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-value-number > object-value-number > object-value-number > object-state-note info-note > children
+console-object-preview.html:20 (3) [0, 0, 2] console-message > source-code > console-message-anchor > devtools-link > 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-value-number > object-value-number > object-value-number > object-state-note info-note > children
 console-object-preview.html:23 Object with many properties console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:28 Object {property_0: 0, property_1: 1, property_2: 2, property_3: 3, property_4: 4…} console-message > source-code > console-message-anchor > devtools-link > 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 > 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:28 Object {property_0: 0, property_1: 1, property_2: 2, property_3: 3, property_4: 4…} console-message > source-code > console-message-anchor > devtools-link > 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-description > 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:30 Array with many properties console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:35 [0, 1, property_0: 0, property_1: 1, property_2: 2, property_3: 3, property_4: 4…] console-message > source-code > console-message-anchor > devtools-link > 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-value-number > 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:35 (2) [0, 1, property_0: 0, property_1: 1, property_2: 2, property_3: 3, property_4: 4…] console-message > source-code > console-message-anchor > devtools-link > 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-value-number > 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:37 Array with gaps and overflow console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:42 [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 > 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 > 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: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 > 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 > 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 > console-message-text
-console-object-preview.html:49 [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, 49, un console-message > source-code > console-message-anchor > devtools-link > 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-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-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) [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 > 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-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-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 > console-message-text
-console-object-preview.html:54 Object {d: 1} console-message > source-code > console-message-anchor > devtools-link > 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 > name > object-value-number > object-state-note info-note > children
+console-object-preview.html:54 Object {d: 1} console-message > source-code > console-message-anchor > devtools-link > 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-description > 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 > console-message-text
-console-object-preview.html:59 [undefined × 50, 50, undefined × 99] console-message > source-code > console-message-anchor > devtools-link > 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-value-undefined > object-value-number > object-value-undefined > object-state-note info-note > children
+console-object-preview.html:59 (150) [undefined × 50, 50, undefined × 99] console-message > source-code > console-message-anchor > devtools-link > 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-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 > console-message-text
-console-object-preview.html:67 [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 > 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-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: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 > 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-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 > console-message-text
-console-object-preview.html:76 Object {" a b ": " a b ", c d: "c d", "": "", "  ": "  ", "a↵↵b↵c": "a↵↵b↵c"} console-message > source-code > console-message-anchor > devtools-link > 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 > name > object-value-string > name > object-value-string > name > object-value-string > name > object-value-string > name > object-value-string > object-state-note info-note > children
+console-object-preview.html:76 Object {" a b ": " a b ", c d: "c d", "": "", "  ": "  ", "a↵↵b↵c": "a↵↵b↵c"} console-message > source-code > console-message-anchor > devtools-link > 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-description > name > object-value-string > name > object-value-string > name > object-value-string > name > object-value-string > name > object-value-string > object-state-note info-note > children
 console-object-preview.html:78 Object with a document.all property console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:79 Object {all: HTMLAllCollection(7)} console-message > source-code > console-message-anchor > devtools-link > 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 > name > object-value-array > object-state-note info-note > children
+console-object-preview.html:79 Object {all: HTMLAllCollection(7)} console-message > source-code > console-message-anchor > devtools-link > 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-description > name > object-value-array > object-state-note info-note > children
 console-object-preview.html:81 Object with special numbers console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:83 Object {nan: NaN, posInf: Infinity, negInf: -Infinity, negZero: -0} console-message > source-code > console-message-anchor > devtools-link > 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 > 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:83 Object {nan: NaN, posInf: Infinity, negInf: -Infinity, negZero: -0} console-message > source-code > console-message-anchor > devtools-link > 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-description > 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:85 Object with exactly 5 properties: expected to be lossless console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:86 Object {a: 1, b: 2, c: 3, d: 4, e: 5} console-message > source-code > console-message-anchor > devtools-link > 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 > 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:88 Object {null: null, undef: undefined, regexp: /^[regexp]$/g, bool: false} console-message > source-code > console-message-anchor > devtools-link > 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 > name > object-value-null > name > object-value-undefined > name > object-value-regexp > name > object-value-boolean > object-state-note info-note > children
+console-object-preview.html:86 Object {a: 1, b: 2, c: 3, d: 4, e: 5} console-message > source-code > console-message-anchor > devtools-link > 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-description > 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:88 Object {null: null, undef: undefined, regexp: /^[regexp]$/g, bool: false} console-message > source-code > console-message-anchor > devtools-link > 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-description > name > object-value-null > name > object-value-undefined > name > object-value-regexp > name > object-value-boolean > object-state-note info-note > children
 Expanded all messages
 console-object-preview.html:9 Mutating object in a loop console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:13 Object {a: 0, b: 0, c: 0}a: 0b: 0c: 2__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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 > name > object-value-number > name > object-value-number > name > 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 > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
-console-object-preview.html:13 Object {a: 0, b: 0, c: 1}a: 0b: 0c: 2__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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 > name > object-value-number > name > object-value-number > name > 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 > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
-console-object-preview.html:13 Object {a: 0, b: 0, c: 2}a: 0b: 0c: 2__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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 > name > object-value-number > name > object-value-number > name > 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 > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
+console-object-preview.html:13 Object {a: 0, b: 0, c: 0}a: 0b: 0c: 2__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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-description > name > object-value-number > name > object-value-number > name > 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 > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
+console-object-preview.html:13 Object {a: 0, b: 0, c: 1}a: 0b: 0c: 2__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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-description > name > object-value-number > name > object-value-number > name > 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 > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
+console-object-preview.html:13 Object {a: 0, b: 0, c: 2}a: 0b: 0c: 2__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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-description > name > object-value-number > name > object-value-number > name > 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 > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
 console-object-preview.html:16 Mutating array in a loop console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:20 [0, 0, 0]0: 01: 02: 2length: 3__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > 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-value-number > object-value-number > 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-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:20 [0, 0, 1]0: 01: 02: 2length: 3__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > 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-value-number > object-value-number > 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-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:20 [0, 0, 2]0: 01: 02: 2length: 3__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > 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-value-number > object-value-number > 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-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:20 (3) [0, 0, 0]0: 01: 02: 2length: 3__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > 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-value-number > object-value-number > 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-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:20 (3) [0, 0, 1]0: 01: 02: 2length: 3__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > 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-value-number > object-value-number > 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-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:20 (3) [0, 0, 2]0: 01: 02: 2length: 3__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > 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-value-number > object-value-number > 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-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:23 Object with many properties console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:28 Object {property_0: 0, property_1: 1, property_2: 2, property_3: 3, property_4: 4…}property_0: 0property_1: 1property_2: 2property_3: 3property_4: 4property_5: 5property_6: 6property_7: 7property_8: 8property_9: 9__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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 > 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 > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > 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
+console-object-preview.html:28 Object {property_0: 0, property_1: 1, property_2: 2, property_3: 3, property_4: 4…}property_0: 0property_1: 1property_2: 2property_3: 3property_4: 4property_5: 5property_6: 6property_7: 7property_8: 8property_9: 9__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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-description > 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 > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > 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
 console-object-preview.html:30 Array with many properties console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:35 [0, 1, property_0: 0, property_1: 1, property_2: 2, property_3: 3, property_4: 4…]0: 01: 1property_0: 0property_1: 1property_2: 2property_3: 3property_4: 4property_5: 5property_6: 6property_7: 7property_8: 8property_9: 9length: 2__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > 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-value-number > 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 > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-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:35 (2) [0, 1, property_0: 0, property_1: 1, property_2: 2, property_3: 3, property_4: 4…]0: 01: 1property_0: 0property_1: 1property_2: 2property_3: 3property_4: 4property_5: 5property_6: 6property_7: 7property_8: 8property_9: 9length: 2__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > 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-value-number > 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 > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-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:37 Array with gaps and overflow console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:42 [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]5732: 100l console-message > source-code > console-message-anchor > devtools-link > 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 > 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: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]573 console-message > source-code > console-message-anchor > devtools-link > 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 > 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 > console-message-text
-console-object-preview.html:49 [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, 49, un console-message > source-code > console-message-anchor > devtools-link > 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-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-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) [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 > 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-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-value-undefined > object-value-number > object-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 > console-message-text
-console-object-preview.html:54 Object {d: 1}d: 1__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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 > 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:54 Object {d: 1}d: 1__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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-description > 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 > console-message-text
-console-object-preview.html:59 [undefined × 50, 50, undefined × 99]50: 50length: 150__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > 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-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) [undefined × 50, 50, undefined × 99]50: 50length: 150__proto__: Array(0) console-message > source-code > console-message-anchor > devtools-link > 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-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 > console-message-text
-console-object-preview.html:67 [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_39: 39pro console-message > source-code > console-message-anchor > devtools-link > 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-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: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_39: console-message > source-code > console-message-anchor > devtools-link > 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-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 > console-message-text
-console-object-preview.html:76 Object {" a b ": " a b ", c d: "c d", "": "", "  ": "  ", "a↵↵b↵c": "a↵↵b↵c"}"": """  ": "  "" a b ": " a b ""a↵↵b↵c": "a↵↵b↵c"c d: "c d"__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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 > name > object-value-string > name > object-value-string > name > object-value-string > name > object-value-string > name > object-value-string > object-state-note info-note > children expanded > selection fill > name > object-properties-section-separator > object-value-string value > object-value-string-quote > object-value-string-quote > children > selection fill > name > object-properties-section-separator > object-value-string value > object-value-string-quote > object-value-string-quote > children > selection fill > name > object-properties-section-separator > object-value-string value > object-value-string-quote > object-value-string-quote > children > selection fill > name > object-properties-section-separator > object-value-string value > object-value-string-quote > object-value-string-quote > children > selection fill > name > object-properties-section-separator > object-value-string value > object-value-string-quote > object-value-string-quote > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
+console-object-preview.html:76 Object {" a b ": " a b ", c d: "c d", "": "", "  ": "  ", "a↵↵b↵c": "a↵↵b↵c"}"": """  ": "  "" a b ": " a b ""a↵↵b↵c": "a↵↵b↵c"c d: "c d"__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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-description > name > object-value-string > name > object-value-string > name > object-value-string > name > object-value-string > name > object-value-string > object-state-note info-note > children expanded > selection fill > name > object-properties-section-separator > object-value-string value > object-value-string-quote > object-value-string-quote > children > selection fill > name > object-properties-section-separator > object-value-string value > object-value-string-quote > object-value-string-quote > children > selection fill > name > object-properties-section-separator > object-value-string value > object-value-string-quote > object-value-string-quote > children > selection fill > name > object-properties-section-separator > object-value-string value > object-value-string-quote > object-value-string-quote > children > selection fill > name > object-properties-section-separator > object-value-string value > object-value-string-quote > object-value-string-quote > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
 console-object-preview.html:78 Object with a document.all property console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:79 Object {all: HTMLAllCollection(7)}all: HTMLAllCollection(7)__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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 > name > object-value-array > object-state-note info-note > children expanded > parent > selection fill > name > object-properties-section-separator > object-value-array value > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
+console-object-preview.html:79 Object {all: HTMLAllCollection(7)}all: HTMLAllCollection(7)__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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-description > name > object-value-array > object-state-note info-note > children expanded > parent > selection fill > name > object-properties-section-separator > object-value-array value > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
 console-object-preview.html:81 Object with special numbers console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:83 Object {nan: NaN, posInf: Infinity, negInf: -Infinity, negZero: -0}nan: NaNnegInf: -InfinitynegZero: -0posInf: Infinity__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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 > name > object-value-number > name > object-value-number > name > object-value-number > name > 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 > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
+console-object-preview.html:83 Object {nan: NaN, posInf: Infinity, negInf: -Infinity, negZero: -0}nan: NaNnegInf: -InfinitynegZero: -0posInf: Infinity__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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-description > name > object-value-number > name > object-value-number > name > object-value-number > name > 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 > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
 console-object-preview.html:85 Object with exactly 5 properties: expected to be lossless console-message > source-code > console-message-anchor > devtools-link > console-message-text
-console-object-preview.html:86 Object {a: 1, b: 2, c: 3, d: 4, e: 5}a: 1b: 2c: 3d: 4e: 5__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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 > 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 > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > 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
-console-object-preview.html:88 Object {null: null, undef: undefined, regexp: /^[regexp]$/g, bool: false}bool: falsenull: nullregexp: /^[regexp]$/gundef: undefined__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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 > name > object-value-null > name > object-value-undefined > name > object-value-regexp > name > object-value-boolean > object-state-note info-note > children expanded > selection fill > name > object-properties-section-separator > object-value-boolean value > children > selection fill > name > object-properties-section-separator > object-value-null value > children > parent > selection fill > name > object-properties-section-separator > object-value-regexp value > children > selection fill > name > object-properties-section-separator > object-value-undefined value > children > parent > selection fill > name object-properties-section-dimmed > object-properties-section-separator > object-value-object value > children
+console-object-preview.html:86 Object {a: 1, b: 2, c: 3, d: 4, e: 5}a: 1b: 2c: 3d: 4e: 5__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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-description > 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 > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > selection fill > name > object-properties-section-separator > object-value-number value > children > 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
+console-object-preview.html:88 Object {null: null, undef: undefined, regexp: /^[regexp]$/g, bool: false}bool: falsenull: nullregexp: /^[regexp]$/gundef: undefined__proto__: Object console-message > source-code > console-message-anchor > devtools-link > 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-description > name > object-value-null > name > object-value-undefined > name > object-value-regexp > name > object-value-boolean > object-state-note info-note > children expanded > selection fill > name > object-properties-section-separator > object-value-boolean value > children > selection fill > name > object-properties-section-separator > object-value-null value > children > parent > selection fill > name > object-properties-section-separator > object-value-regexp value > children > selection fill > name > object-properties-section-separator > object-value-undefined value > 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-proxy-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-proxy-expected.txt
index 88a8f6f0..fcf39382 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-proxy-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-proxy-expected.txt
@@ -2,11 +2,11 @@
 CONSOLE MESSAGE: line 23: [object Proxy]
 Tests that console logging dumps proxy properly.
 
-console-proxy.html:21 Proxy {boo: 42, foo: 43} console-message > source-code > console-message-anchor > devtools-link > console-message-text > console-view-object-properties-section object-value-proxy 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 > name > object-value-number > name > object-value-number > object-state-note info-note > children
-console-proxy.html:23 Proxy {boo: 42, foo: 43} console-message > source-code > console-message-anchor > devtools-link > console-message-text > console-view-object-properties-section object-value-proxy 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 > name > object-value-number > name > object-value-number > object-state-note info-note > children
+console-proxy.html:21 Proxy {boo: 42, foo: 43} console-message > source-code > console-message-anchor > devtools-link > console-message-text > console-view-object-properties-section object-value-proxy 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 > name > object-value-number > name > object-value-number > object-state-note info-note > children
+console-proxy.html:23 Proxy {boo: 42, foo: 43} console-message > source-code > console-message-anchor > devtools-link > console-message-text > console-view-object-properties-section object-value-proxy 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 > name > object-value-number > name > object-value-number > object-state-note info-note > children
 window.accessedGet = false
 info-note display: inline-block
-console-proxy.html:21 Proxy {boo: 42, foo: 43}[[Handler]]: Object[[Target]]: Object[[IsRevoked]]: false console-message > source-code > console-message-anchor > devtools-link > console-message-text > console-view-object-properties-section object-value-proxy 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 > name > object-value-number > name > object-value-number > object-state-note info-note > children expanded > parent > selection fill > name > object-properties-section-separator > object-value-object value > children > parent > selection fill > name > object-properties-section-separator > object-value-object value > children > selection fill > name > object-properties-section-separator > object-value-boolean value > children
-console-proxy.html:23 Proxy {boo: 42, foo: 43}[[Handler]]: Object[[Target]]: Proxy[[IsRevoked]]: false console-message > source-code > console-message-anchor > devtools-link > console-message-text > console-view-object-properties-section object-value-proxy 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 > name > object-value-number > name > object-value-number > object-state-note info-note > children expanded > parent > selection fill > name > object-properties-section-separator > object-value-object value > children > parent > selection fill > name > object-properties-section-separator > object-value-proxy value > children > selection fill > name > object-properties-section-separator > object-value-boolean value > children
+console-proxy.html:21 Proxy {boo: 42, foo: 43}[[Handler]]: Object[[Target]]: Object[[IsRevoked]]: false console-message > source-code > console-message-anchor > devtools-link > console-message-text > console-view-object-properties-section object-value-proxy 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 > name > object-value-number > name > object-value-number > object-state-note info-note > children expanded > parent > selection fill > name > object-properties-section-separator > object-value-object value > children > parent > selection fill > name > object-properties-section-separator > object-value-object value > children > selection fill > name > object-properties-section-separator > object-value-boolean value > children
+console-proxy.html:23 Proxy {boo: 42, foo: 43}[[Handler]]: Object[[Target]]: Proxy[[IsRevoked]]: false console-message > source-code > console-message-anchor > devtools-link > console-message-text > console-view-object-properties-section object-value-proxy 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 > name > object-value-number > name > object-value-number > object-state-note info-note > children expanded > parent > selection fill > name > object-properties-section-separator > object-value-object value > children > parent > selection fill > name > object-properties-section-separator > object-value-proxy value > children > selection fill > name > object-properties-section-separator > object-value-boolean value > children
 window.accessedGet = false
 
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-save-to-temp-var-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-save-to-temp-var-expected.txt
index c080021..3666ebd8 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-save-to-temp-var-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-save-to-temp-var-expected.txt
@@ -16,11 +16,11 @@
 temp11
 -0
 temp12
-[1, 2, NaN, -0, null, undefined]
+(6) [1, 2, NaN, -0, null, undefined]
 temp13
 Object {foo: "bar"}
 temp14
-[1, 2, 3, 4, callee: function, Symbol(Symbol.iterator): function]
+(4) [1, 2, 3, 4, callee: function, Symbol(Symbol.iterator): function]
 temp15
 function func() {}
 temp16
diff --git a/third_party/WebKit/LayoutTests/inspector/console/console-tainted-globals-expected.txt b/third_party/WebKit/LayoutTests/inspector/console/console-tainted-globals-expected.txt
index d37be47..a666744 100644
--- a/third_party/WebKit/LayoutTests/inspector/console/console-tainted-globals-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/console/console-tainted-globals-expected.txt
@@ -7,13 +7,13 @@
 
 Running: dumpConsoleMessages
 testOverriddenArrayPushAndMathMax()
-[1, 2, 3]
+(3) [1, 2, 3]
 testOverriddenConstructorName()
 Object {constructor: Object}
 testThrowConstructorName()
 Object {}
 testOverriddenIsFinite()
-["arg1", "arg2", callee: function, Symbol(Symbol.iterator): function]
+(2) ["arg1", "arg2", callee: function, Symbol(Symbol.iterator): function]
 testOverriddenError()
 Object {result: "PASS"}
 restoreError()
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 b0503d7c..d52cf9c 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
@@ -36,7 +36,7 @@
 =========== 8< ==========
 [ 8]       debugger; 	
 [ 9]       var a = { k: 1 }; 	 a = Object {k: 1}
-[10]       var b = [1, 2, 3, 4, 5]; 	 b = [1, 2, 3, 4, 5]
+[10]       var b = [1, 2, 3, 4, 5]; 	 b = (5) [1, 2, 3, 4, 5]
 [11] >     var c = new Array(100); c[10] = 1; 	
 [12]       a.k = 2; 	
 [13]       a.l = window; 	
@@ -47,7 +47,7 @@
 =========== 8< ==========
 [ 8]       debugger; 	
 [ 9]       var a = { k: 1 }; 	 a = Object {k: 1}
-[10]       var b = [1, 2, 3, 4, 5]; 	 b = [1, 2, 3, 4, 5]
+[10]       var b = [1, 2, 3, 4, 5]; 	 b = (5) [1, 2, 3, 4, 5]
 [11] >     var c = new Array(100); c[10] = 1; 	
 [12]       a.k = 2; 	
 [13]       a.l = window; 	
@@ -58,8 +58,8 @@
 =========== 8< ==========
 [ 8]       debugger; 	
 [ 9]       var a = { k: 1 }; 	 a = Object {k: 1}
-[10]       var b = [1, 2, 3, 4, 5]; 	 b = [1, 2, 3, 4, 5]
-[11]       var c = new Array(100); c[10] = 1; 	 c = [undefined × 10, 1, undefined × 89]
+[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]
 [12] >     a.k = 2; 	
 [13]       a.l = window; 	
 [14]       b[1]++; 	
@@ -69,8 +69,8 @@
 =========== 8< ==========
 [ 8]       debugger; 	
 [ 9]       var a = { k: 1 }; 	 a = Object {k: 2}
-[10]       var b = [1, 2, 3, 4, 5]; 	 b = [1, 2, 3, 4, 5]
-[11]       var c = new Array(100); c[10] = 1; 	 c = [undefined × 10, 1, undefined × 89]
+[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]
 [12]       a.k = 2; 	 a = Object {k: 2}
 [13] >     a.l = window; 	
 [14]       b[1]++; 	
@@ -80,8 +80,8 @@
 =========== 8< ==========
 [ 8]       debugger; 	
 [ 9]       var a = { k: 1 }; 	 a = Object {k: 2, l: Window}
-[10]       var b = [1, 2, 3, 4, 5]; 	 b = [1, 2, 3, 4, 5]
-[11]       var c = new Array(100); c[10] = 1; 	 c = [undefined × 10, 1, undefined × 89]
+[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]
 [12]       a.k = 2; 	 a = Object {k: 2, l: Window}
 [13]       a.l = window; 	 
 [14] >     b[1]++; 	
@@ -91,22 +91,22 @@
 =========== 8< ==========
 [ 8]       debugger; 	
 [ 9]       var a = { k: 1 }; 	 a = Object {k: 2, l: Window}
-[10]       var b = [1, 2, 3, 4, 5]; 	 b = [1, 3, 3, 4, 5]
-[11]       var c = new Array(100); c[10] = 1; 	 c = [undefined × 10, 1, undefined × 89]
+[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]
 [12]       a.k = 2; 	 a = Object {k: 2, l: Window}
 [13]       a.l = window; 	 
-[14]       b[1]++; 	 b = [1, 3, 3, 4, 5]
+[14]       b[1]++; 	 b = (5) [1, 3, 3, 4, 5]
 [15] >     b[2] = document.body; 	
 [16]   } 	
 [17]    	
 =========== 8< ==========
 [ 8]       debugger; 	
 [ 9]       var a = { k: 1 }; 	 a = Object {k: 2, l: Window}
-[10]       var b = [1, 2, 3, 4, 5]; 	 b = [1, 3, body, 4, 5]
-[11]       var c = new Array(100); c[10] = 1; 	 c = [undefined × 10, 1, undefined × 89]
+[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]
 [12]       a.k = 2; 	 a = Object {k: 2, l: Window}
 [13]       a.l = window; 	 
-[14]       b[1]++; 	 b = [1, 3, body, 4, 5]
+[14]       b[1]++; 	 b = (5) [1, 3, body, 4, 5]
 [15]       b[2] = document.body; 	 
 [16] > } 	
 [17]    	
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/debugger-save-to-temp-var-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/debugger-save-to-temp-var-expected.txt
index 8b9f8151..a0c2cfb 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/debugger-save-to-temp-var-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/debugger-save-to-temp-var-expected.txt
@@ -17,11 +17,11 @@
 temp11
 -0
 temp12
-[1, 2, NaN, -0, null, undefined]
+(6) [1, 2, NaN, -0, null, undefined]
 temp13
 Object {foo: "bar"}
 temp14
-[1, 2, 3, 4, callee: function, Symbol(Symbol.iterator): function]
+(4) [1, 2, 3, 4, callee: function, Symbol(Symbol.iterator): function]
 temp15
 function func() {}
 temp16
diff --git a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/inline-scope-variables-expected.txt b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/inline-scope-variables-expected.txt
index 1e34a9b4..244038b 100644
--- a/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/inline-scope-variables-expected.txt
+++ b/third_party/WebKit/LayoutTests/inspector/sources/debugger-ui/inline-scope-variables-expected.txt
@@ -3,8 +3,8 @@
 
 Set timer for test function.
 9: length = 123
-10: a = [1, 2, 3]
+10: a = (3) [1, 2, 3]
 11: 
 12: b = 42
-13: a = [1, 2, 3]
+13: a = (3) [1, 2, 3]
 
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/buffer-usage.html b/third_party/WebKit/LayoutTests/inspector/tracing/buffer-usage.html
index ff7b9c2..64e2a39 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing/buffer-usage.html
+++ b/third_party/WebKit/LayoutTests/inspector/tracing/buffer-usage.html
@@ -46,7 +46,7 @@
         }
     };
     var performanceModel = new Timeline.PerformanceModel();
-    var controller = new Timeline.TimelineController(SDK.targetManager.mainTarget(), performanceModel, new TestTimelineControllerClient());
+    var controller = new Timeline.TimelineController(InspectorTest.tracingManager, performanceModel, new TestTimelineControllerClient());
     controller.startRecording({}, []).then(() => {
         InspectorTest.addResult("TimelineControllerClient.recordingStarted");
     });
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-aggregated-details.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-aggregated-details.html
index 6b63a49..08f86b1 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-aggregated-details.html
+++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-aggregated-details.html
@@ -620,7 +620,7 @@
     {
         InspectorTest.addResult("");
         timeline._tabbedPane.selectTab(type, true);
-        var callTree = timeline._currentViews[0]._treeView;
+        var callTree = timeline._currentView._treeView;
         if (grouping) {
             InspectorTest.addResult(type + "  Group by: " + grouping);
             callTree._groupByCombobox.select(callTree._groupByCombobox.options().find(x => x.value === grouping));
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-flame-chart-automatically-size-window.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-flame-chart-automatically-size-window.html
index 652d137..3707495 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-flame-chart-automatically-size-window.html
+++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-flame-chart-automatically-size-window.html
@@ -10,7 +10,7 @@
 {
     var timeline = UI.panels.timeline;
     timeline._onModeChanged();
-    timeline._currentViews[0]._automaticallySizeWindow = true;
+    timeline._currentView._automaticallySizeWindow = true;
 
     function requestWindowTimesHook(startTime, endTime)
     {
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-tree-search.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-tree-search.html
index 55ed6bd..926bdf8 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-tree-search.html
+++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-tree-search.html
@@ -68,7 +68,7 @@
         InspectorTest.addResult(count);
         for (var i = 0; i < count + 2; ++i) {
             view._onNextButtonSearch();
-            var node = panel._currentViews[0]._treeView.lastSelectedNode();
+            var node = panel._currentView._treeView.lastSelectedNode();
             InspectorTest.addResult(Timeline.TimelineUIUtils.eventTitle(node.event));
         }
     }
diff --git a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-window-filter.html b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-window-filter.html
index ff2656f..a65f5ec 100644
--- a/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-window-filter.html
+++ b/third_party/WebKit/LayoutTests/inspector/tracing/timeline-misc/timeline-window-filter.html
@@ -33,7 +33,7 @@
 
     function dumpFlameChartRecordsCountForRange(windowLeft, windowRight)
     {
-        var mainView = timeline._currentViews[0]._mainView;
+        var mainView = timeline._currentView._mainFlameChart;
         mainView._muteAnimation = true;
         overviewPane._overviewGrid.setWindow(windowLeft, windowRight);
         mainView.update();
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt
index 93b2dc5..640e9505 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt
@@ -3,9 +3,9 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-layer at (0,42) size 800x558 clip at (0,42) size 785x558 scrollY 284.00 scrollHeight 842
+layer at (0,42) size 800x558 scrollY 284.00 scrollHeight 842
   LayoutBlockFlow (positioned) {DIV} at (0,42) size 800x558
-layer at (0,-242) size 559x842 backgroundClip at (0,42) size 785x558 clip at (0,42) size 785x558
+layer at (0,-242) size 559x842 backgroundClip at (0,42) size 800x558 clip at (0,42) size 800x558
   LayoutBlockFlow (positioned) {DIV} at (0,0) size 558.97x842
     LayoutBlockFlow (anonymous) at (0,0) size 558.97x20
       LayoutText {#text} at (0,0) size 559x19
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.png b/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.png
index d25a784a..21e4412 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.png
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.png
Binary files differ
diff --git a/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.txt b/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.txt
index 234f305..a79d5c45 100644
--- a/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/linux/fast/text/emoji-web-font-expected.txt
@@ -7,8 +7,8 @@
         LayoutText {#text} at (0,0) size 500x19
           text run at (0,0) width 500: "Following should show Asterisk with FruitGirl similar to Asterisk Image below"
       LayoutBlockFlow {P} at (0,45) size 784x25
-        LayoutText {#text} at (0,0) size 0x25
-          text run at (0,0) width 0: "*"
+        LayoutText {#text} at (0,0) size 17x25
+          text run at (0,0) width 17: "*"
       LayoutBlockFlow (anonymous) at (0,95) size 784x25
         LayoutImage {IMG} at (0,0) size 25x25
         LayoutText {#text} at (0,0) size 0x0
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt
index 504b9d26..e4d13bce2 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.10/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt
@@ -3,9 +3,9 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-layer at (0,42) size 800x558 clip at (0,42) size 785x558 scrollY 278.00 scrollHeight 836
+layer at (0,42) size 800x558 scrollY 278.00 scrollHeight 836
   LayoutBlockFlow (positioned) {DIV} at (0,42) size 800x558
-layer at (0,-236) size 570x836 backgroundClip at (0,42) size 785x558 clip at (0,42) size 785x558
+layer at (0,-236) size 570x836 backgroundClip at (0,42) size 800x558 clip at (0,42) size 800x558
   LayoutBlockFlow (positioned) {DIV} at (0,0) size 570.41x836
     LayoutBlockFlow (anonymous) at (0,0) size 570.41x18
       LayoutText {#text} at (0,0) size 571x18
diff --git a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt
index 9e0ca43..cbf97bd 100644
--- a/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac-mac10.9/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt
@@ -3,9 +3,9 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-layer at (0,42) size 800x558 clip at (0,42) size 785x558 scrollY 278.00 scrollHeight 836
+layer at (0,42) size 800x558 scrollY 278.00 scrollHeight 836
   LayoutBlockFlow (positioned) {DIV} at (0,42) size 800x558
-layer at (0,-236) size 570x836 backgroundClip at (0,42) size 785x558 clip at (0,42) size 785x558
+layer at (0,-236) size 570x836 backgroundClip at (0,42) size 800x558 clip at (0,42) size 800x558
   LayoutBlockFlow (positioned) {DIV} at (0,0) size 570.41x836
     LayoutBlockFlow (anonymous) at (0,0) size 570.41x18
       LayoutText {#text} at (0,0) size 571x18
diff --git a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt
index f8ebb28..9faa65ef 100644
--- a/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/mac/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt
@@ -3,9 +3,9 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-layer at (0,42) size 800x558 clip at (0,42) size 785x558 scrollY 278.00 scrollHeight 836
+layer at (0,42) size 800x558 scrollY 278.00 scrollHeight 836
   LayoutBlockFlow (positioned) {DIV} at (0,42) size 800x558
-layer at (0,-236) size 570x836 backgroundClip at (0,42) size 785x558 clip at (0,42) size 785x558
+layer at (0,-236) size 570x836 backgroundClip at (0,42) size 800x558 clip at (0,42) size 800x558
   LayoutBlockFlow (positioned) {DIV} at (0,0) size 570.41x836
     LayoutBlockFlow (anonymous) at (0,0) size 570.41x18
       LayoutText {#text} at (0,0) size 571x18
diff --git a/third_party/WebKit/LayoutTests/platform/win/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt b/third_party/WebKit/LayoutTests/platform/win/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt
index 15e5c4c..d652bc4 100644
--- a/third_party/WebKit/LayoutTests/platform/win/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt
+++ b/third_party/WebKit/LayoutTests/platform/win/fast/overflow/scroll-nested-positioned-layer-in-overflow-expected.txt
@@ -3,9 +3,9 @@
 layer at (0,0) size 800x600
   LayoutBlockFlow {HTML} at (0,0) size 800x600
     LayoutBlockFlow {BODY} at (8,8) size 784x584
-layer at (0,42) size 800x558 clip at (0,42) size 785x558 scrollY 282.00 scrollHeight 840
+layer at (0,42) size 800x558 scrollY 282.00 scrollHeight 840
   LayoutBlockFlow (positioned) {DIV} at (0,42) size 800x558
-layer at (0,-240) size 571x840 backgroundClip at (0,42) size 785x558 clip at (0,42) size 785x558
+layer at (0,-240) size 571x840 backgroundClip at (0,42) size 800x558 clip at (0,42) size 800x558
   LayoutBlockFlow (positioned) {DIV} at (0,0) size 571.28x840
     LayoutBlockFlow (anonymous) at (0,0) size 571.28x18
       LayoutText {#text} at (0,0) size 572x17
diff --git a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/animation-direction-expected.txt b/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/animation-direction-expected.txt
deleted file mode 100644
index 94bf551..0000000
--- a/third_party/WebKit/LayoutTests/typedcssom/inlinestyle/properties/animation-direction-expected.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-This is a testharness.js-based test.
-PASS Setting animation-direction to normal 
-PASS Setting animation-direction to reverse 
-PASS Setting animation-direction to alternate 
-PASS Setting animation-direction to alternate-reverse 
-PASS Setting animation-direction to initial 
-PASS Setting animation-direction to inherit 
-PASS Setting animation-direction to unset 
-PASS Setting animation-direction to invalid value CSSSimpleLength throws 
-PASS Setting animation-direction to invalid value null throws 
-PASS Setting animation-direction to invalid value undefined throws 
-PASS Setting animation-direction to invalid value true throws 
-PASS Setting animation-direction to invalid value false throws 
-PASS Setting animation-direction to invalid value 1 throws 
-PASS Setting animation-direction to invalid value hello throws 
-PASS Setting animation-direction to invalid value [object Object] throws 
-PASS Setting animation-direction to invalid value CSSKeywordValue throws 
-PASS Getting animation-direction when it is set to normal 
-PASS Getting animation-direction when it is set to reverse 
-PASS Getting animation-direction when it is set to alternate 
-PASS Getting animation-direction when it is set to alternate-reverse 
-PASS Getting animation-direction when it is set to initial 
-PASS Getting animation-direction when it is set to inherit 
-PASS Getting animation-direction when it is set to unset 
-PASS getAll for single-valued animation-direction 
-PASS getAll for list-valued animation-direction 
-PASS Delete animation-direction removes the value from the styleMap 
-PASS animation-direction shows up in getProperties 
-FAIL Set animation-direction to a sequence assert_equals: expected "normal, normal" but got "normal normal"
-PASS Set animation-direction to a sequence containing an invalid type 
-FAIL Appending a CSSKeywordValue to animation-direction assert_equals: expected "normal, normal" but got "normal normal"
-FAIL Append a sequence to animation-direction assert_equals: expected "normal, normal" but got "normal normal"
-PASS Appending an invalid value to animation-direction 
-PASS Append a sequence containing an invalid value to animation-direction 
-Harness: the test ran to completion.
-
diff --git a/third_party/WebKit/LayoutTests/virtual/prefer_compositing_to_lcd_text/compositing/overflow/overflow-overlay-with-touch-expected.txt b/third_party/WebKit/LayoutTests/virtual/prefer_compositing_to_lcd_text/compositing/overflow/overflow-overlay-with-touch-expected.txt
index ff9be7c..326a19b 100644
--- a/third_party/WebKit/LayoutTests/virtual/prefer_compositing_to_lcd_text/compositing/overflow/overflow-overlay-with-touch-expected.txt
+++ b/third_party/WebKit/LayoutTests/virtual/prefer_compositing_to_lcd_text/compositing/overflow/overflow-overlay-with-touch-expected.txt
@@ -15,7 +15,7 @@
     },
     {
       "name": "Scrolling Layer",
-      "bounds": [285, 285],
+      "bounds": [300, 300],
       "shouldFlattenTransform": false
     },
     {
diff --git a/third_party/WebKit/PerformanceTests/resources/runner.js b/third_party/WebKit/PerformanceTests/resources/runner.js
index 2df0dde..22a5e8e 100644
--- a/third_party/WebKit/PerformanceTests/resources/runner.js
+++ b/third_party/WebKit/PerformanceTests/resources/runner.js
@@ -163,6 +163,11 @@
 
     function scheduleNextRun(scheduler, runner) {
         scheduler(function () {
+            // This will be used by tools/perf/benchmarks/blink_perf.py to find
+            // traces during the measured runs.
+            if (completedIterations >= 0)
+                console.time("blink_perf");
+
             try {
                 if (currentTest.setup)
                     currentTest.setup();
@@ -204,6 +209,7 @@
 
     function finish() {
         try {
+            console.timeEnd("blink_perf");
             if (currentTest.description)
                 PerfTestRunner.log("Description: " + currentTest.description);
             PerfTestRunner.logStatistics(results, PerfTestRunner.unit, "Time:");
diff --git a/third_party/WebKit/Source/build/scripts/make_css_property_metadata.py b/third_party/WebKit/Source/build/scripts/make_css_property_metadata.py
index b7ebe71c..022e19cd 100755
--- a/third_party/WebKit/Source/build/scripts/make_css_property_metadata.py
+++ b/third_party/WebKit/Source/build/scripts/make_css_property_metadata.py
@@ -28,7 +28,6 @@
                          ('interpolable', 'isInterpolableProperty'),
                          ('inherited', 'isInheritedProperty'),
                          ('supports_percentage', 'propertySupportsPercentage'),
-                         ('repeated', 'propertyIsRepeated')
                         ],
             'first_enum_value': self._first_enum_value,
         }
diff --git a/third_party/WebKit/Source/build/scripts/templates/CSSPropertyMetadata.cpp.tmpl b/third_party/WebKit/Source/build/scripts/templates/CSSPropertyMetadata.cpp.tmpl
index cc7ea78..3b2ae3d 100644
--- a/third_party/WebKit/Source/build/scripts/templates/CSSPropertyMetadata.cpp.tmpl
+++ b/third_party/WebKit/Source/build/scripts/templates/CSSPropertyMetadata.cpp.tmpl
@@ -10,9 +10,9 @@
 {% for flag, function_name in switches %}
 
 bool CSSPropertyMetadata::{{function_name}}(CSSPropertyID property) {
-  switch(property) {
+  switch (property) {
     case CSSPropertyInvalid:
-      ASSERT_NOT_REACHED();
+      NOTREACHED();
       return false;
     {% for property_id, property in properties.items() if property[flag] %}
     case {{property_id}}:
@@ -27,6 +27,21 @@
 }
 {% endfor %}
 
+char CSSPropertyMetadata::repetitionSeparator(CSSPropertyID property) {
+  switch (property) {
+  {% for property_id, property in properties.items() if property.separator %}
+  case {{property_id}}:
+    return '{{property.separator}}';
+  {% endfor %}
+  default:
+    return 0;
+  }
+}
+
+bool CSSPropertyMetadata::propertyIsRepeated(CSSPropertyID property) {
+  return repetitionSeparator(property) != 0;
+}
+
 bool CSSPropertyMetadata::isEnabledProperty(CSSPropertyID unresolvedProperty) {
   CSSPropertyID property = resolveCSSPropertyID(unresolvedProperty);
   static std::bitset<numCSSProperties>* enabledProperties = nullptr;
diff --git a/third_party/WebKit/Source/core/BUILD.gn b/third_party/WebKit/Source/core/BUILD.gn
index 7876782..47586a3 100644
--- a/third_party/WebKit/Source/core/BUILD.gn
+++ b/third_party/WebKit/Source/core/BUILD.gn
@@ -1264,6 +1264,7 @@
     "html/parser/HTMLTreeBuilderSimulatorTest.cpp",
     "html/parser/HTMLViewSourceParserTest.cpp",
     "html/parser/TextResourceDecoderTest.cpp",
+    "html/shadow/MediaControlsLeakTest.cpp",
     "html/shadow/MediaControlsOrientationLockDelegateTest.cpp",
     "html/shadow/MediaControlsTest.cpp",
     "html/track/TextTrackListTest.cpp",
diff --git a/third_party/WebKit/Source/core/css/BUILD.gn b/third_party/WebKit/Source/core/css/BUILD.gn
index 7bca7e6..6d07116 100644
--- a/third_party/WebKit/Source/core/css/BUILD.gn
+++ b/third_party/WebKit/Source/core/css/BUILD.gn
@@ -389,6 +389,7 @@
     "properties/CSSPropertyAPILetterAndWordSpacing.cpp",
     "properties/CSSPropertyAPIMargin.cpp",
     "properties/CSSPropertyAPIMarker.cpp",
+    "properties/CSSPropertyAPIOffsetAnchor.cpp",
     "properties/CSSPropertyAPIOffsetDistance.cpp",
     "properties/CSSPropertyAPIOffsetPosition.cpp",
     "properties/CSSPropertyAPIOffsetRotate.cpp",
diff --git a/third_party/WebKit/Source/core/css/CSSProperties.json5 b/third_party/WebKit/Source/core/css/CSSProperties.json5
index d977be7e..73271fe7 100644
--- a/third_party/WebKit/Source/core/css/CSSProperties.json5
+++ b/third_party/WebKit/Source/core/css/CSSProperties.json5
@@ -96,16 +96,16 @@
     // - typedom_types: ["Type", "OtherType"]
     // The property can take types specified in typedom_types for CSS Typed OM.
     // Keyword does not need to be specified as every property can take keywords.
-    // - repeated
-    // The property supports a list of values.
+    // - separator
+    // The property supports a list of values, and when there is more than one,
+    // it is separated with this character.
     // - supports_percentage
     // The property supports percentage types.
     typedom_types: {
       default: [],
     },
-    repeated: {
-      default: false,
-      valid_type: "bool",
+    separator: {
+      valid_values: [",", " ", "/"],
     },
     supports_percentage: {
       default: false,
@@ -260,7 +260,7 @@
       custom_all: true,
       keywords: ["normal", "reverse", "alternate", "alternate-reverse"],
       priority: "Animation",
-      repeated: true,
+      separator: ",",
     },
     {
       name: "animation-duration",
@@ -277,7 +277,7 @@
       custom_all: true,
       keywords: ["infinite"],
       priority: "Animation",
-      repeated: true,
+      separator: ",",
     },
     {
       name: "animation-name",
@@ -879,7 +879,7 @@
       api_class: true,
       api_methods: ["parseSingleValue"],
       custom_all: true,
-      repeated: true,
+      separator: ",",
       typedom_types: ["Image"],
     },
     {
@@ -1321,6 +1321,8 @@
     },
     {
       name: "offset-anchor",
+      api_class: true,
+      api_methods: ["parseSingleValue"],
       converter: "convertPositionOrAuto",
       interpolable: true,
       runtime_flag: "CSSOffsetPositionAnchor",
diff --git a/third_party/WebKit/Source/core/css/CSSPropertyMetadata.h b/third_party/WebKit/Source/core/css/CSSPropertyMetadata.h
index c90641a5..31b30bd6a 100644
--- a/third_party/WebKit/Source/core/css/CSSPropertyMetadata.h
+++ b/third_party/WebKit/Source/core/css/CSSPropertyMetadata.h
@@ -21,6 +21,7 @@
   static bool isInheritedProperty(CSSPropertyID);
   static bool propertySupportsPercentage(CSSPropertyID);
   static bool propertyIsRepeated(CSSPropertyID);
+  static char repetitionSeparator(CSSPropertyID);
   static bool isDescriptorOnly(CSSPropertyID);
 
   static void filterEnabledCSSPropertiesIntoVector(const CSSPropertyID*,
diff --git a/third_party/WebKit/Source/core/css/cssom/InlineStylePropertyMap.cpp b/third_party/WebKit/Source/core/css/cssom/InlineStylePropertyMap.cpp
index edcc24f27..0374b75 100644
--- a/third_party/WebKit/Source/core/css/cssom/InlineStylePropertyMap.cpp
+++ b/third_party/WebKit/Source/core/css/cssom/InlineStylePropertyMap.cpp
@@ -21,6 +21,21 @@
 
 namespace {
 
+CSSValueList* cssValueListForPropertyID(CSSPropertyID propertyID) {
+  char separator = CSSPropertyMetadata::repetitionSeparator(propertyID);
+  switch (separator) {
+    case ' ':
+      return CSSValueList::createSpaceSeparated();
+    case ',':
+      return CSSValueList::createCommaSeparated();
+    case '/':
+      return CSSValueList::createSlashSeparated();
+    default:
+      NOTREACHED();
+      return nullptr;
+  }
+}
+
 const CSSValue* styleValueToCSSValue(CSSPropertyID propertyID,
                                      const CSSStyleValue& styleValue) {
   if (!CSSOMTypes::propertyCanTake(propertyID, styleValue))
@@ -38,16 +53,15 @@
       cssValue->isCSSWideKeyword())
     return cssValue;
 
-  // TODO(meade): Determine the correct separator for each property.
-  CSSValueList* valueList = CSSValueList::createSpaceSeparated();
+  CSSValueList* valueList = cssValueListForPropertyID(propertyID);
   valueList->append(*cssValue);
   return valueList;
 }
 
-CSSValueList* asCSSValueList(CSSPropertyID propertyID,
-                             const CSSStyleValueVector& styleValueVector) {
-  // TODO(meade): Determine the correct separator for each property.
-  CSSValueList* valueList = CSSValueList::createSpaceSeparated();
+const CSSValueList* asCSSValueList(
+    CSSPropertyID propertyID,
+    const CSSStyleValueVector& styleValueVector) {
+  CSSValueList* valueList = cssValueListForPropertyID(propertyID);
   for (const CSSStyleValue* value : styleValueVector) {
     const CSSValue* cssValue = styleValueToCSSValue(propertyID, *value);
     if (!cssValue) {
@@ -151,8 +165,7 @@
           propertyID);
   CSSValueList* cssValueList = nullptr;
   if (!cssValue) {
-    // TODO(meade): Determine the correct separator for each property.
-    cssValueList = CSSValueList::createSpaceSeparated();
+    cssValueList = cssValueListForPropertyID(propertyID);
   } else if (cssValue->isValueList()) {
     cssValueList = toCSSValueList(cssValue)->copy();
   } else {
diff --git a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
index 52e4430..1e5b59d5 100644
--- a/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
+++ b/third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp
@@ -912,14 +912,6 @@
   return list;
 }
 
-static CSSValue* consumeOffsetAnchor(CSSParserTokenRange& range,
-                                     CSSParserMode cssParserMode) {
-  CSSValueID id = range.peek().id();
-  if (id == CSSValueAuto)
-    return consumeIdent(range);
-  return consumePosition(range, cssParserMode, UnitlessQuirk::Forbid);
-}
-
 static CSSValue* consumeOffsetPath(CSSParserTokenRange& range,
                                    const CSSParserContext* context,
                                    bool isMotionPath) {
@@ -2158,8 +2150,6 @@
     case CSSPropertyWebkitTextDecorationsInEffect:
     case CSSPropertyTextDecorationLine:
       return consumeTextDecorationLine(m_range);
-    case CSSPropertyOffsetAnchor:
-      return consumeOffsetAnchor(m_range, m_context->mode());
     case CSSPropertyD:
       return consumePathOrNone(m_range);
     case CSSPropertyOffsetPath:
diff --git a/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIOffsetAnchor.cpp b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIOffsetAnchor.cpp
new file mode 100644
index 0000000..152004e
--- /dev/null
+++ b/third_party/WebKit/Source/core/css/properties/CSSPropertyAPIOffsetAnchor.cpp
@@ -0,0 +1,24 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/css/properties/CSSPropertyAPIOffsetAnchor.h"
+
+#include "core/css/CSSValuePair.h"
+#include "core/css/parser/CSSParserContext.h"
+#include "core/css/parser/CSSParserTokenRange.h"
+#include "core/css/parser/CSSPropertyParserHelpers.h"
+
+namespace blink {
+
+const CSSValue* CSSPropertyAPIOffsetAnchor::parseSingleValue(
+    CSSParserTokenRange& range,
+    const CSSParserContext* context) {
+  CSSValueID id = range.peek().id();
+  if (id == CSSValueAuto)
+    return CSSPropertyParserHelpers::consumeIdent(range);
+  return consumePosition(range, context->mode(),
+                         CSSPropertyParserHelpers::UnitlessQuirk::Forbid);
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/dom/Document.cpp b/third_party/WebKit/Source/core/dom/Document.cpp
index 423ca14..c982b408 100644
--- a/third_party/WebKit/Source/core/dom/Document.cpp
+++ b/third_party/WebKit/Source/core/dom/Document.cpp
@@ -689,7 +689,7 @@
 }
 
 AtomicString Document::convertLocalName(const AtomicString& name) {
-  return isHTMLDocument() ? name.lower() : name;
+  return isHTMLDocument() ? name.lowerASCII() : name;
 }
 
 // https://dom.spec.whatwg.org/#dom-document-createelement
diff --git a/third_party/WebKit/Source/core/dom/QualifiedName.cpp b/third_party/WebKit/Source/core/dom/QualifiedName.cpp
index 28ac626..1ab21b15 100644
--- a/third_party/WebKit/Source/core/dom/QualifiedName.cpp
+++ b/third_party/WebKit/Source/core/dom/QualifiedName.cpp
@@ -126,7 +126,7 @@
 
 const AtomicString& QualifiedName::localNameUpper() const {
   if (!m_impl->m_localNameUpper)
-    m_impl->m_localNameUpper = m_impl->m_localName.upper();
+    m_impl->m_localNameUpper = m_impl->m_localName.upperASCII();
   return m_impl->m_localNameUpper;
 }
 
diff --git a/third_party/WebKit/Source/core/frame/FrameViewTest.cpp b/third_party/WebKit/Source/core/frame/FrameViewTest.cpp
index e4f7f9c0..e78918f7 100644
--- a/third_party/WebKit/Source/core/frame/FrameViewTest.cpp
+++ b/third_party/WebKit/Source/core/frame/FrameViewTest.cpp
@@ -43,7 +43,7 @@
     mockSetToolTip(&frame, tooltipText, dir);
   }
 
-  void scheduleAnimation(Widget*) override { m_hasScheduledAnimation = true; }
+  void scheduleAnimation(FrameViewBase*) override { m_hasScheduledAnimation = true; }
   bool m_hasScheduledAnimation;
 };
 
diff --git a/third_party/WebKit/Source/core/html/HTMLElement.cpp b/third_party/WebKit/Source/core/html/HTMLElement.cpp
index 6c85e35..f032cf0 100644
--- a/third_party/WebKit/Source/core/html/HTMLElement.cpp
+++ b/third_party/WebKit/Source/core/html/HTMLElement.cpp
@@ -114,8 +114,8 @@
 
 String HTMLElement::debugNodeName() const {
   if (document().isHTMLDocument()) {
-    return tagQName().hasPrefix() ? Element::nodeName().upper()
-                                  : tagQName().localName().upper();
+    return tagQName().hasPrefix() ? Element::nodeName().upperASCII()
+                                  : tagQName().localName().upperASCII();
   }
   return Element::nodeName();
 }
@@ -131,7 +131,7 @@
   if (document().isHTMLDocument()) {
     if (!tagQName().hasPrefix())
       return tagQName().localNameUpper();
-    return Element::nodeName().upper();
+    return Element::nodeName().upperASCII();
   }
   return Element::nodeName();
 }
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
index 3d5cff44..087b101 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControls.cpp
@@ -688,6 +688,27 @@
   return contains(relatedTarget->toNode());
 }
 
+void MediaControls::onInsertedIntoDocument() {
+  // TODO(mlamouri): we should show the controls instead of having
+  // HTMLMediaElement do it.
+
+  // m_windowEventListener doesn't need to be re-attached as it's only needed
+  // when a menu is visible.
+  m_mediaEventListener->attach();
+  if (m_orientationLockDelegate)
+    m_orientationLockDelegate->attach();
+}
+
+void MediaControls::onRemovedFromDocument() {
+  // TODO(mlamouri): we hide show the controls instead of having
+  // HTMLMediaElement do it.
+
+  m_windowEventListener->stop();
+  m_mediaEventListener->detach();
+  if (m_orientationLockDelegate)
+    m_orientationLockDelegate->detach();
+}
+
 void MediaControls::onVolumeChange() {
   m_muteButton->updateDisplayType();
   m_volumeSlider->setVolume(mediaElement().muted() ? 0
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControls.h b/third_party/WebKit/Source/core/html/shadow/MediaControls.h
index 7480531..c38bf9d 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControls.h
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControls.h
@@ -166,6 +166,8 @@
   bool containsRelatedTarget(Event*);
 
   // Methods called by MediaControlsMediaEventListener.
+  void onInsertedIntoDocument();
+  void onRemovedFromDocument();
   void onVolumeChange();
   void onFocusIn();
   void onTimeUpdate();
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlsLeakTest.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlsLeakTest.cpp
new file mode 100644
index 0000000..a6b3704fc
--- /dev/null
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControlsLeakTest.cpp
@@ -0,0 +1,78 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "core/html/shadow/MediaControls.h"
+
+#include "core/dom/Document.h"
+#include "core/html/HTMLVideoElement.h"
+#include "core/testing/DummyPageHolder.h"
+#include "platform/geometry/IntSize.h"
+#include "platform/heap/ThreadState.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace blink {
+
+class MediaControlsLeakTest : public ::testing::Test {
+ protected:
+  virtual void SetUp() {
+    m_pageHolder = DummyPageHolder::create(IntSize(800, 600));
+    Document& document = this->document();
+
+    document.write("<body><video controls></video></body>");
+    m_video = toHTMLVideoElement(document.querySelector("video"));
+    m_controls = m_video->mediaControls();
+  }
+
+  Document& document() { return m_pageHolder->document(); }
+  HTMLVideoElement* video() { return m_video; }
+  MediaControls* controls() { return m_controls; }
+
+ private:
+  std::unique_ptr<DummyPageHolder> m_pageHolder;
+  WeakPersistent<HTMLVideoElement> m_video;
+  WeakPersistent<MediaControls> m_controls;
+};
+
+TEST_F(MediaControlsLeakTest, RemovingFromDocumentCollectsAll) {
+  ASSERT_NE(video(), nullptr);
+  EXPECT_TRUE(video()->hasEventListeners());
+  EXPECT_NE(controls(), nullptr);
+  EXPECT_TRUE(document().hasEventListeners());
+
+  document().body()->setInnerHTML("");
+
+  // When removed from the document, the event listeners should have been
+  // dropped.
+  EXPECT_FALSE(document().hasEventListeners());
+  // The video element should still have some event listeners.
+  EXPECT_TRUE(video()->hasEventListeners());
+
+  ThreadState::current()->collectAllGarbage();
+
+  // They have been GC'd.
+  EXPECT_EQ(video(), nullptr);
+  EXPECT_EQ(controls(), nullptr);
+}
+
+TEST_F(MediaControlsLeakTest, ReInsertingInDocumentCollectsControls) {
+  ASSERT_NE(video(), nullptr);
+  EXPECT_TRUE(video()->hasEventListeners());
+  EXPECT_NE(controls(), nullptr);
+  EXPECT_TRUE(document().hasEventListeners());
+
+  // This should be a no-op.
+  document().body()->removeChild(video());
+  document().body()->appendChild(video());
+
+  EXPECT_TRUE(document().hasEventListeners());
+  EXPECT_TRUE(video()->hasEventListeners());
+
+  ThreadState::current()->collectAllGarbage();
+
+  ASSERT_NE(video(), nullptr);
+  EXPECT_NE(controls(), nullptr);
+  EXPECT_EQ(controls(), video()->mediaControls());
+}
+
+}  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.cpp
index 7d20343..76d680d 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.cpp
@@ -14,6 +14,18 @@
 MediaControlsMediaEventListener::MediaControlsMediaEventListener(
     MediaControls* mediaControls)
     : EventListener(CPPEventListenerType), m_mediaControls(mediaControls) {
+  // These events are always active because they are needed in order to attach
+  // or detach the whole controls.
+  mediaElement().addEventListener(EventTypeNames::DOMNodeInsertedIntoDocument,
+                                  this, false);
+  mediaElement().addEventListener(EventTypeNames::DOMNodeRemovedFromDocument,
+                                  this, false);
+
+  if (mediaElement().isConnected())
+    attach();
+}
+
+void MediaControlsMediaEventListener::attach() {
   mediaElement().addEventListener(EventTypeNames::volumechange, this, false);
   mediaElement().addEventListener(EventTypeNames::focusin, this, false);
   mediaElement().addEventListener(EventTypeNames::timeupdate, this, false);
@@ -37,6 +49,16 @@
   textTracks->addEventListener(EventTypeNames::removetrack, this, false);
 }
 
+void MediaControlsMediaEventListener::detach() {
+  m_mediaControls->document().removeEventListener(
+      EventTypeNames::fullscreenchange, this, false);
+
+  TextTrackList* textTracks = mediaElement().textTracks();
+  textTracks->removeEventListener(EventTypeNames::addtrack, this, false);
+  textTracks->removeEventListener(EventTypeNames::change, this, false);
+  textTracks->removeEventListener(EventTypeNames::removetrack, this, false);
+}
+
 bool MediaControlsMediaEventListener::operator==(
     const EventListener& other) const {
   return this == &other;
@@ -49,6 +71,14 @@
 void MediaControlsMediaEventListener::handleEvent(
     ExecutionContext* executionContext,
     Event* event) {
+  if (event->type() == EventTypeNames::DOMNodeInsertedIntoDocument) {
+    m_mediaControls->onInsertedIntoDocument();
+    return;
+  }
+  if (event->type() == EventTypeNames::DOMNodeRemovedFromDocument) {
+    m_mediaControls->onRemovedFromDocument();
+    return;
+  }
   if (event->type() == EventTypeNames::volumechange) {
     m_mediaControls->onVolumeChange();
     return;
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.h b/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.h
index cd88cb44..a6532029 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.h
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControlsMediaEventListener.h
@@ -16,6 +16,15 @@
  public:
   explicit MediaControlsMediaEventListener(MediaControls*);
 
+  // Called by MediaControls when the HTMLMediaElement is added to a document
+  // document. All event listeners should be added.
+  void attach();
+
+  // Called by MediaControls when the HTMLMediaElement is no longer in the
+  // document. All event listeners should be removed in order to prepare the
+  // object to be garbage collected.
+  void detach();
+
   bool operator==(const EventListener&) const override;
 
   DECLARE_VIRTUAL_TRACE();
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.cpp b/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.cpp
index 624bb9d..f29c4c5e 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.cpp
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.cpp
@@ -64,12 +64,25 @@
 MediaControlsOrientationLockDelegate::MediaControlsOrientationLockDelegate(
     HTMLVideoElement& video)
     : EventListener(CPPEventListenerType), m_videoElement(video) {
+  if (videoElement().isConnected())
+    attach();
+}
+
+void MediaControlsOrientationLockDelegate::attach() {
   document().addEventListener(EventTypeNames::fullscreenchange, this, true);
   videoElement().addEventListener(EventTypeNames::webkitfullscreenchange, this,
                                   true);
   videoElement().addEventListener(EventTypeNames::loadedmetadata, this, true);
 }
 
+void MediaControlsOrientationLockDelegate::detach() {
+  document().removeEventListener(EventTypeNames::fullscreenchange, this, true);
+  videoElement().removeEventListener(EventTypeNames::webkitfullscreenchange,
+                                     this, true);
+  videoElement().removeEventListener(EventTypeNames::loadedmetadata, this,
+                                     true);
+}
+
 bool MediaControlsOrientationLockDelegate::operator==(
     const EventListener& other) const {
   return this == &other;
diff --git a/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.h b/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.h
index c30cb7b7..cb87959 100644
--- a/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.h
+++ b/third_party/WebKit/Source/core/html/shadow/MediaControlsOrientationLockDelegate.h
@@ -43,6 +43,15 @@
  public:
   explicit MediaControlsOrientationLockDelegate(HTMLVideoElement&);
 
+  // Called by MediaControls when the HTMLMediaElement is added to a document
+  // document. All event listeners should be added.
+  void attach();
+
+  // Called by MediaControls when the HTMLMediaElement is no longer in the
+  // document. All event listeners should be removed in order to prepare the
+  // object to be garbage collected.
+  void detach();
+
   // EventListener implementation.
   bool operator==(const EventListener&) const override;
 
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 141da8c..7608224 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
@@ -310,8 +310,8 @@
     : node_(node),
       constraint_space_(constraint_space),
       break_token_(break_token),
-      builder_(WTF::wrapUnique(
-          new NGFragmentBuilder(NGPhysicalFragment::kFragmentBox, node))) {}
+      builder_(NGPhysicalFragment::kFragmentBox, node),
+      space_builder_(constraint_space_) {}
 
 Optional<MinAndMaxContentSizes>
 NGBlockLayoutAlgorithm::ComputeMinAndMaxContentSizes() const {
@@ -360,20 +360,20 @@
   LayoutUnit block_offset = content_size_;
   if (known_fragment_offset) {
     block_offset = known_fragment_offset.value().block_offset -
-                   builder_->BfcOffset().value().block_offset;
+                   builder_.BfcOffset().value().block_offset;
   }
   return {inline_offset, block_offset};
 }
 
 void NGBlockLayoutAlgorithm::UpdateFragmentBfcOffset(
     const NGLogicalOffset& offset) {
-  if (!builder_->BfcOffset()) {
+  if (!builder_.BfcOffset()) {
     NGLogicalOffset bfc_offset = offset;
     if (ConstraintSpace().ClearanceOffset()) {
       bfc_offset.block_offset = std::max(
           ConstraintSpace().ClearanceOffset().value(), offset.block_offset);
     }
-    builder_->SetBfcOffset(bfc_offset);
+    builder_.SetBfcOffset(bfc_offset);
   }
 }
 
@@ -400,16 +400,15 @@
   if (adjusted_block_size != NGSizeIndefinite)
     adjusted_block_size -= border_and_padding_.BlockSum();
 
-  space_builder_ = new NGConstraintSpaceBuilder(constraint_space_);
   space_builder_
-      ->SetAvailableSize(
+      .SetAvailableSize(
           NGLogicalSize(adjusted_inline_size, adjusted_block_size))
       .SetPercentageResolutionSize(
           NGLogicalSize(adjusted_inline_size, adjusted_block_size));
 
-  builder_->SetDirection(constraint_space_->Direction());
-  builder_->SetWritingMode(constraint_space_->WritingMode());
-  builder_->SetInlineSize(inline_size).SetBlockSize(block_size);
+  builder_.SetDirection(constraint_space_->Direction());
+  builder_.SetWritingMode(constraint_space_->WritingMode());
+  builder_.SetInlineSize(inline_size).SetBlockSize(block_size);
 
   NGBlockChildIterator child_iterator(node_->FirstChild(), break_token_);
   NGBlockChildIterator::Entry entry = child_iterator.NextChild();
@@ -437,7 +436,7 @@
   // still {} as the margin strut from the constraint space must also be empty.
   if (ConstraintSpace().IsNewFormattingContext()) {
     UpdateFragmentBfcOffset(curr_bfc_offset_);
-    DCHECK_EQ(builder_->BfcOffset().value(), NGLogicalOffset());
+    DCHECK_EQ(builder_.BfcOffset().value(), NGLogicalOffset());
     DCHECK_EQ(curr_margin_strut_, NGMarginStrut());
   }
 
@@ -448,8 +447,8 @@
       NGBlockNode* current_block_child = toNGBlockNode(child);
       EPosition position = current_block_child->Style().position();
       if (position == EPosition::kAbsolute || position == EPosition::kFixed) {
-        builder_->AddOutOfFlowChildCandidate(current_block_child,
-                                             GetChildSpaceOffset());
+        builder_.AddOutOfFlowChildCandidate(current_block_child,
+                                            GetChildSpaceOffset());
         NGBlockChildIterator::Entry entry = child_iterator.NextChild();
         child = entry.node;
         child_break_token = entry.token;
@@ -491,17 +490,17 @@
   // Recompute the block-axis size now that we know our content size.
   block_size =
       ComputeBlockSizeForFragment(ConstraintSpace(), Style(), content_size_);
-  builder_->SetBlockSize(block_size);
+  builder_.SetBlockSize(block_size);
 
   // Layout our absolute and fixed positioned children.
-  NGOutOfFlowLayoutPart(ConstraintSpace(), Style(), builder_.get()).Run();
+  NGOutOfFlowLayoutPart(ConstraintSpace(), Style(), &builder_).Run();
 
   // Non-empty blocks always know their position in space:
   if (block_size) {
     curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
     UpdateFragmentBfcOffset(curr_bfc_offset_);
     PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(),
-                          builder_.get());
+                          &builder_);
   }
 
   // Margins collapsing:
@@ -511,14 +510,14 @@
     // TODO(glebl): handle minLogicalHeight, maxLogicalHeight.
     curr_margin_strut_ = NGMarginStrut();
   }
-  builder_->SetEndMarginStrut(curr_margin_strut_);
+  builder_.SetEndMarginStrut(curr_margin_strut_);
 
-  builder_->SetInlineOverflow(max_inline_size_).SetBlockOverflow(content_size_);
+  builder_.SetInlineOverflow(max_inline_size_).SetBlockOverflow(content_size_);
 
   if (ConstraintSpace().HasBlockFragmentation())
     FinalizeForFragmentation();
 
-  return builder_->ToBoxFragment();
+  return builder_.ToBoxFragment();
 }
 
 void NGBlockLayoutAlgorithm::LayoutInlineChildren(
@@ -553,7 +552,7 @@
   // 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.
-  builder_->MutableUnpositionedFloats().appendVector(
+  builder_.MutableUnpositionedFloats().appendVector(
       layout_result->UnpositionedFloats());
 
   if (child->Type() == NGLayoutInputNode::kLegacyBlock &&
@@ -562,16 +561,16 @@
         layout_result->PhysicalFragment().get(), child_space, constraint_space_,
         toNGBlockNode(child), toNGBlockNode(child)->Style(),
         curr_child_margins_);
-    builder_->AddUnpositionedFloat(floating_object);
+    builder_.AddUnpositionedFloat(floating_object);
     // No need to postpone the positioning if we know the correct offset.
-    if (builder_->BfcOffset()) {
+    if (builder_.BfcOffset()) {
       NGLogicalOffset origin_point = curr_bfc_offset_;
       // Adjust origin point to the margins of the last child.
       // Example: <div style="margin-bottom: 20px"><float></div>
       //          <div style="margin-bottom: 30px"></div>
       origin_point.block_offset += curr_margin_strut_.Sum();
       PositionPendingFloats(origin_point.block_offset, ConstraintSpace(),
-                            builder_.get());
+                            &builder_);
     }
     return;
   }
@@ -589,7 +588,7 @@
     // Fragment that knows its offset can be used to set parent's BFC position.
     curr_bfc_offset_.block_offset = fragment.BfcOffset().value().block_offset;
     bfc_offset = curr_bfc_offset_;
-  } else if (builder_->BfcOffset()) {
+  } else if (builder_.BfcOffset()) {
     // Fragment doesn't know its offset but we can still calculate its BFC
     // position because the parent fragment's BFC is known.
     // Example:
@@ -602,7 +601,7 @@
   if (bfc_offset) {
     UpdateFragmentBfcOffset(curr_bfc_offset_);
     PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(),
-                          builder_.get());
+                          &builder_);
   }
   NGLogicalOffset logical_offset = CalculateLogicalOffset(bfc_offset);
 
@@ -624,7 +623,7 @@
                                      curr_child_margins_.InlineSum() +
                                      border_and_padding_.InlineSum());
 
-  builder_->AddChild(layout_result, logical_offset);
+  builder_.AddChild(layout_result, logical_offset);
 }
 
 void NGBlockLayoutAlgorithm::FinalizeForFragmentation() {
@@ -638,33 +637,33 @@
       << "Adding and subtracting the used_block_size shouldn't leave the "
          "block_size for this fragment smaller than zero.";
 
-  DCHECK(builder_->BfcOffset()) << "We must have our BfcOffset by this point "
-                                   "to determine the space left in the flow.";
+  DCHECK(builder_.BfcOffset()) << "We must have our BfcOffset by this point "
+                                  "to determine the space left in the flow.";
   LayoutUnit space_left = ConstraintSpace().FragmentainerSpaceAvailable() -
-                          builder_->BfcOffset().value().block_offset;
+                          builder_.BfcOffset().value().block_offset;
   DCHECK_GE(space_left, LayoutUnit());
 
-  if (builder_->DidBreak()) {
+  if (builder_.DidBreak()) {
     // One of our children broke. Even if we fit within the remaining space we
     // need to prepare a break token.
-    builder_->SetUsedBlockSize(std::min(space_left, block_size) +
-                               used_block_size);
-    builder_->SetBlockSize(std::min(space_left, block_size));
-    builder_->SetBlockOverflow(space_left);
+    builder_.SetUsedBlockSize(std::min(space_left, block_size) +
+                              used_block_size);
+    builder_.SetBlockSize(std::min(space_left, block_size));
+    builder_.SetBlockOverflow(space_left);
     return;
   }
 
   if (block_size > space_left) {
     // Need a break inside this block.
-    builder_->SetUsedBlockSize(space_left + used_block_size);
-    builder_->SetBlockSize(space_left);
-    builder_->SetBlockOverflow(space_left);
+    builder_.SetUsedBlockSize(space_left + used_block_size);
+    builder_.SetBlockSize(space_left);
+    builder_.SetBlockOverflow(space_left);
     return;
   }
 
   // The end of the block fits in the current fragmentainer.
-  builder_->SetBlockSize(block_size);
-  builder_->SetBlockOverflow(content_size_);
+  builder_.SetBlockSize(block_size);
+  builder_.SetBlockOverflow(content_size_);
 }
 
 NGBoxStrut NGBlockLayoutAlgorithm::CalculateMargins(
@@ -698,10 +697,10 @@
     curr_bfc_offset_.block_offset += curr_margin_strut_.Sum();
     UpdateFragmentBfcOffset(curr_bfc_offset_);
     PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(),
-                          builder_.get());
+                          &builder_);
     curr_margin_strut_ = {};
 
-    return space_builder_->ToConstraintSpace(
+    return space_builder_.ToConstraintSpace(
         FromPlatformWritingMode(Style().getWritingMode()));
   }
 
@@ -710,12 +709,12 @@
 
   // Calculate margins in parent's writing mode.
   curr_child_margins_ = CalculateMargins(
-      block_child, *space_builder_->ToConstraintSpace(
+      block_child, *space_builder_.ToConstraintSpace(
                        FromPlatformWritingMode(Style().getWritingMode())));
 
   bool is_new_bfc = IsNewFormattingContextForInFlowBlockLevelChild(
       ConstraintSpace(), child_style);
-  space_builder_->SetIsNewFormattingContext(is_new_bfc)
+  space_builder_.SetIsNewFormattingContext(is_new_bfc)
       .SetIsShrinkToFit(ShouldShrinkToFit(ConstraintSpace(), child_style))
       .SetTextDirection(child_style.direction());
 
@@ -732,15 +731,15 @@
       curr_child_margins_.block_start = LayoutUnit();
     }
     PositionPendingFloats(curr_bfc_offset_.block_offset, ConstraintSpace(),
-                          builder_.get());
+                          &builder_);
     WTF::Optional<LayoutUnit> clearance_offset =
         GetClearanceOffset(constraint_space_->Exclusions(), child_style);
-    space_builder_->SetClearanceOffset(clearance_offset);
+    space_builder_.SetClearanceOffset(clearance_offset);
   }
 
   // Set estimated BFC offset to the next child's constraint space.
-  curr_bfc_offset_ = builder_->BfcOffset() ? builder_->BfcOffset().value()
-                                           : ConstraintSpace().BfcOffset();
+  curr_bfc_offset_ = builder_.BfcOffset() ? builder_.BfcOffset().value()
+                                          : ConstraintSpace().BfcOffset();
   curr_bfc_offset_.block_offset += content_size_;
   curr_bfc_offset_.inline_offset += border_and_padding_.inline_start;
 
@@ -753,10 +752,10 @@
     // Non empty border/padding use cases are handled inside of the child's
     // layout.
     curr_margin_strut_.Append(curr_child_margins_.block_start);
-    space_builder_->SetMarginStrut(curr_margin_strut_);
+    space_builder_.SetMarginStrut(curr_margin_strut_);
   }
 
-  space_builder_->SetBfcOffset(curr_bfc_offset_);
+  space_builder_.SetBfcOffset(curr_bfc_offset_);
 
   LayoutUnit space_available;
   if (constraint_space_->HasBlockFragmentation()) {
@@ -765,13 +764,13 @@
     // position in the formatting context, and are able to adjust the
     // fragmentation line.
     if (is_new_bfc) {
-      DCHECK(builder_->BfcOffset());
+      DCHECK(builder_.BfcOffset());
       space_available -= curr_bfc_offset_.block_offset;
     }
   }
-  space_builder_->SetFragmentainerSpaceAvailable(space_available);
+  space_builder_.SetFragmentainerSpaceAvailable(space_available);
 
-  return space_builder_->ToConstraintSpace(
+  return space_builder_.ToConstraintSpace(
       FromPlatformWritingMode(child_style.getWritingMode()));
 }
 }  // 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 24b3d45d..3c4aa93 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
@@ -8,6 +8,7 @@
 #include "core/CoreExport.h"
 #include "core/layout/ng/ng_block_node.h"
 #include "core/layout/ng/ng_break_token.h"
+#include "core/layout/ng/ng_constraint_space_builder.h"
 #include "core/layout/ng/ng_fragment_builder.h"
 #include "core/layout/ng/ng_layout_algorithm.h"
 #include "core/layout/ng/ng_units.h"
@@ -18,7 +19,6 @@
 class ComputedStyle;
 class NGBlockBreakToken;
 class NGConstraintSpace;
-class NGConstraintSpaceBuilder;
 class NGInlineNode;
 class NGLayoutResult;
 
@@ -82,8 +82,8 @@
   // The break token from which we are currently resuming layout.
   Persistent<NGBlockBreakToken> break_token_;
 
-  std::unique_ptr<NGFragmentBuilder> builder_;
-  Persistent<NGConstraintSpaceBuilder> space_builder_;
+  NGFragmentBuilder builder_;
+  NGConstraintSpaceBuilder space_builder_;
 
   NGBoxStrut border_and_padding_;
   LayoutUnit content_size_;
diff --git a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h
index ddf0703a..c4e5bf1 100644
--- a/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h
+++ b/third_party/WebKit/Source/core/layout/ng/ng_constraint_space_builder.h
@@ -7,12 +7,14 @@
 
 #include "core/layout/ng/ng_constraint_space.h"
 #include "core/layout/ng/ng_units.h"
+#include "wtf/Allocator.h"
 #include "wtf/Optional.h"
 
 namespace blink {
 
-class CORE_EXPORT NGConstraintSpaceBuilder final
-    : public GarbageCollectedFinalized<NGConstraintSpaceBuilder> {
+class CORE_EXPORT NGConstraintSpaceBuilder final {
+  DISALLOW_NEW();
+
  public:
   NGConstraintSpaceBuilder(const NGConstraintSpace* parent_space);
 
@@ -63,8 +65,6 @@
   // NGWritingMode specifies the writing mode of the generated space.
   NGConstraintSpace* ToConstraintSpace(NGWritingMode);
 
-  DEFINE_INLINE_TRACE() {}
-
  private:
   // Relative to parent_writing_mode_.
   NGLogicalSize available_size_;
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 3a82c44..c6aafd0 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/ng_floating_object.h"
 #include "core/layout/ng/ng_physical_fragment.h"
 #include "core/layout/ng/ng_units.h"
+#include "wtf/Allocator.h"
 
 namespace blink {
 
@@ -17,6 +18,8 @@
 class NGPhysicalTextFragment;
 
 class CORE_EXPORT NGFragmentBuilder final {
+  DISALLOW_NEW();
+
  public:
   NGFragmentBuilder(NGPhysicalFragment::NGFragmentType, NGLayoutInputNode*);
 
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
index 5e1cd751..c8523dc 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableArea.cpp
@@ -1284,10 +1284,12 @@
     OverlayScrollbarClipBehavior overlayScrollbarClipBehavior) const {
   if (!hasVerticalScrollbar())
     return 0;
-  if (verticalScrollbar()->isOverlayScrollbar() &&
+  if ((verticalScrollbar()->isOverlayScrollbar() ||
+       box().style()->overflowY() == EOverflow::kOverlay) &&
       (overlayScrollbarClipBehavior == IgnoreOverlayScrollbarSize ||
-       !verticalScrollbar()->shouldParticipateInHitTesting()))
+       !verticalScrollbar()->shouldParticipateInHitTesting())) {
     return 0;
+  }
   return verticalScrollbar()->scrollbarThickness();
 }
 
@@ -1295,10 +1297,12 @@
     OverlayScrollbarClipBehavior overlayScrollbarClipBehavior) const {
   if (!hasHorizontalScrollbar())
     return 0;
-  if (horizontalScrollbar()->isOverlayScrollbar() &&
+  if ((horizontalScrollbar()->isOverlayScrollbar() ||
+       box().style()->overflowX() == EOverflow::kOverlay) &&
       (overlayScrollbarClipBehavior == IgnoreOverlayScrollbarSize ||
-       !horizontalScrollbar()->shouldParticipateInHitTesting()))
+       !horizontalScrollbar()->shouldParticipateInHitTesting())) {
     return 0;
+  }
   return horizontalScrollbar()->scrollbarThickness();
 }
 
diff --git a/third_party/WebKit/Source/core/paint/PaintLayerScrollableAreaTest.cpp b/third_party/WebKit/Source/core/paint/PaintLayerScrollableAreaTest.cpp
index 216494b..2567e0ba6 100644
--- a/third_party/WebKit/Source/core/paint/PaintLayerScrollableAreaTest.cpp
+++ b/third_party/WebKit/Source/core/paint/PaintLayerScrollableAreaTest.cpp
@@ -10,6 +10,7 @@
 #include "core/paint/PaintLayer.h"
 #include "platform/graphics/GraphicsLayer.h"
 #include "platform/scroll/ScrollTypes.h"
+#include "platform/scroll/ScrollbarTheme.h"
 #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
@@ -548,4 +549,22 @@
       .Times(0);
   scrollableArea->setScrollOffset(ScrollOffset(2, 2), ProgrammaticScroll);
 }
+
+TEST_F(PaintLayerScrollableAreaTest, IncludeOverlayScrollbarsInVisibleWidth) {
+  RuntimeEnabledFeatures::setOverlayScrollbarsEnabled(false);
+  setBodyInnerHTML(
+      "<style>"
+      "#scroller { overflow: overlay; height: 100px; width: 100px; }"
+      "#scrolled { width: 100px; height: 200px; }"
+      "</style>"
+      "<div id=\"scroller\"><div id=\"scrolled\"></div></div>");
+  document().view()->updateAllLifecyclePhases();
+  Element* scroller = document().getElementById("scroller");
+  ASSERT_TRUE(scroller);
+  PaintLayerScrollableArea* scrollableArea =
+      toLayoutBoxModelObject(scroller->layoutObject())->getScrollableArea();
+  ASSERT_TRUE(scrollableArea);
+  scrollableArea->setScrollOffset(ScrollOffset(100, 0), ClampingScroll);
+  EXPECT_EQ(scrollableArea->getScrollOffset().width(), 0);
+}
 }
diff --git a/third_party/WebKit/Source/devtools/BUILD.gn b/third_party/WebKit/Source/devtools/BUILD.gn
index 336033b..36f41cf 100644
--- a/third_party/WebKit/Source/devtools/BUILD.gn
+++ b/third_party/WebKit/Source/devtools/BUILD.gn
@@ -657,7 +657,6 @@
   "front_end/ui/SoftContextMenu.js",
   "front_end/ui/splitWidget.css",
   "front_end/ui/SplitWidget.js",
-  "front_end/ui/StackView.js",
   "front_end/ui/suggestBox.css",
   "front_end/ui/SuggestBox.js",
   "front_end/ui/tabbedPane.css",
diff --git a/third_party/WebKit/Source/devtools/PRESUBMIT.py b/third_party/WebKit/Source/devtools/PRESUBMIT.py
index 8078939..1623692 100644
--- a/third_party/WebKit/Source/devtools/PRESUBMIT.py
+++ b/third_party/WebKit/Source/devtools/PRESUBMIT.py
@@ -31,11 +31,8 @@
 for more details about the presubmit API built into gcl.
 """
 
-from collections import namedtuple
 import sys
 
-CheckOutput = namedtuple('CheckOutput', ['results', 'has_errors'])
-
 
 def _CheckNodeAndNPMModules(input_api, output_api):
     node_script_path = input_api.os_path.join(input_api.PresubmitLocalPath(), "scripts", "install_node_deps.py")
@@ -43,14 +40,18 @@
         [input_api.python_executable, node_script_path], stdout=input_api.subprocess.PIPE, stderr=input_api.subprocess.STDOUT)
     out, _ = process.communicate()
     if process.returncode != 0:
-        return CheckOutput([output_api.PresubmitError(out)], has_errors=True)
-    return CheckOutput([output_api.PresubmitNotifyResult(out)], has_errors=False)
+        return [output_api.PresubmitError(out)]
+    return [output_api.PresubmitNotifyResult(out)]
 
 
-def _FormatDevtools(input_api, output_api):
+def _CheckFormat(input_api, output_api):
+
+    def popen(args):
+        return input_api.subprocess.Popen(args=args, stdout=input_api.subprocess.PIPE, stderr=input_api.subprocess.STDOUT)
+
     affected_files = _getAffectedJSFiles(input_api)
     if len(affected_files) == 0:
-        return CheckOutput([], has_errors=False)
+        return []
     original_sys_path = sys.path
     try:
         sys.path = sys.path + [input_api.os_path.join(input_api.PresubmitLocalPath(), "scripts")]
@@ -59,39 +60,34 @@
         sys.path = original_sys_path
 
     node_path, _ = install_node_deps.resolve_node_paths()
-    format_path = input_api.os_path.join(input_api.PresubmitLocalPath(), "scripts", "format.js")
-    glob_arg = "--glob=" + ",".join(affected_files)
-    check_formatting_process = _inputPopen(input_api, args=[node_path, format_path] + [glob_arg, "--output-replacements-xml"])
-    check_formatting_out, _ = check_formatting_process.communicate()
-    if check_formatting_process.returncode != 0:
-        return CheckOutput([output_api.PresubmitError(check_formatting_out)], has_errors=True)
-    if "</replacement>" not in check_formatting_out:
-        return CheckOutput([output_api.PresubmitNotifyResult("CL is properly formatted")], has_errors=False)
 
-    format_args = [node_path, format_path] + [glob_arg]
-    format_process = _inputPopen(input_api, format_args)
-    format_process_out, _ = format_process.communicate()
+    check_formatting_process = popen(['git', 'cl', 'format', '--js', '--dry-run', input_api.PresubmitLocalPath()])
+    check_formatting_process.communicate()
+    if check_formatting_process.returncode == 0:
+        return []
+
+    format_args = ['git', 'cl', 'format', '--js', input_api.PresubmitLocalPath()]
+    format_process = popen(format_args)
+    format_out, _ = format_process.communicate()
+    if format_process.returncode != 0:
+        return [output_api.PresubmitError(format_out)]
 
     # Use eslint to autofix the braces
     eslint_path = input_api.os_path.join(input_api.PresubmitLocalPath(), "node_modules", ".bin", "eslint")
-    eslint_process = _inputPopen(
-        input_api,
-        [node_path, eslint_path, '--no-eslintrc', '--fix', '--env=es6', '--rule={"curly": [2, "multi-or-nest", "consistent"]}'] +
-        affected_files)
+    eslint_process = popen([
+        node_path, eslint_path, '--no-eslintrc', '--fix', '--env=es6', '--rule={"curly": [2, "multi-or-nest", "consistent"]}'
+    ] + affected_files)
     eslint_process.communicate()
 
     # Need to run clang-format again to align the braces
-    reformat_process = _inputPopen(input_api, format_args)
-    reformat_process.communicate()
+    popen(format_args).communicate()
 
-    return CheckOutput(
-        [
-            output_api.PresubmitError("ERROR: Found formatting violations.\n"
-                                      "Ran clang-format on files changed in CL\n"
-                                      "Use git status to check the formatting changes"),
-            output_api.PresubmitError(format_process_out)
-        ],
-        has_errors=True)
+    return [
+        output_api.PresubmitError("ERROR: Found formatting violations in third_party/WebKit/Source/devtools.\n"
+                                  "Ran clang-format on diff\n"
+                                  "Use git status to check the formatting changes"),
+        output_api.PresubmitError(format_out),
+    ]
 
 
 def _CheckDevtoolsStyle(input_api, output_api):
@@ -188,19 +184,8 @@
 
 def CheckChangeOnUpload(input_api, output_api):
     results = []
-
-    (node_results, has_errors) = _CheckNodeAndNPMModules(input_api, output_api)
-    results.extend(node_results)
-    if has_errors:
-        results.append(output_api.PresubmitError("ERROR: Bailed out early because error using node.js/npm"))
-        return results
-
-    (format_results, has_errors) = _FormatDevtools(input_api, output_api)
-    results.extend(format_results)
-    if has_errors:
-        results.append(output_api.PresubmitError("ERROR: Bailed out early because formatting errors were found"))
-        return results
-
+    results.extend(_CheckNodeAndNPMModules(input_api, output_api))
+    results.extend(_CheckFormat(input_api, output_api))
     results.extend(_CheckDevtoolsStyle(input_api, output_api))
     results.extend(_CompileDevtoolsFrontend(input_api, output_api))
     results.extend(_CheckConvertSVGToPNGHashes(input_api, output_api))
@@ -233,7 +218,3 @@
         if (devtools_front_end in file_name or devtools_scripts in file_name) and file_name.endswith(".js")
     ]
     return [input_api.os_path.relpath(file_name, devtools_root) for file_name in affected_js_files]
-
-
-def _inputPopen(input_api, args):
-    return input_api.subprocess.Popen(args, stdout=input_api.subprocess.PIPE, stderr=input_api.subprocess.STDOUT)
diff --git a/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js b/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js
index e435228..084a5c4 100644
--- a/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js
+++ b/third_party/WebKit/Source/devtools/front_end/console/ConsoleView.js
@@ -168,8 +168,6 @@
     this._registerWithMessageSink();
     SDK.targetManager.observeTargets(this);
 
-    this._initConsoleMessages();
-
     UI.context.addFlavorChangeListener(SDK.ExecutionContext, this._executionContextChanged, this);
 
     this._messagesElement.addEventListener('mousedown', this._updateStickToBottomOnMouseDown.bind(this), false);
@@ -210,14 +208,14 @@
     this._prompt.setAddCompletionsFromHistory(this._consoleHistoryAutocompleteSetting.get());
   }
 
-  _initConsoleMessages() {
-    var mainTarget = SDK.targetManager.mainTarget();
-    var resourceTreeModel = mainTarget && SDK.ResourceTreeModel.fromTarget(mainTarget);
-    var resourcesLoaded = !resourceTreeModel || resourceTreeModel.cachedResourcesLoaded();
-    if (!mainTarget || !resourcesLoaded) {
-      SDK.targetManager.addModelListener(
-          SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._onResourceTreeModelLoaded,
-          this);
+  /**
+   * @param {!SDK.Target} target
+   */
+  _initConsoleMessages(target) {
+    var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(target);
+    if (resourceTreeModel && !resourceTreeModel.cachedResourcesLoaded()) {
+      resourceTreeModel.addEventListener(
+          SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._onResourceTreeModelLoaded, this);
       return;
     }
     this._fetchMultitargetMessages();
@@ -228,11 +226,8 @@
    */
   _onResourceTreeModelLoaded(event) {
     var resourceTreeModel = /** @type {!SDK.ResourceTreeModel} */ (event.data);
-    if (resourceTreeModel.target() !== SDK.targetManager.mainTarget())
-      return;
-    SDK.targetManager.removeModelListener(
-        SDK.ResourceTreeModel, SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._onResourceTreeModelLoaded,
-        this);
+    resourceTreeModel.removeEventListener(
+        SDK.ResourceTreeModel.Events.CachedResourcesLoaded, this._onResourceTreeModelLoaded, this);
     this._fetchMultitargetMessages();
   }
 
@@ -287,6 +282,8 @@
    * @param {!SDK.Target} target
    */
   targetAdded(target) {
+    if (target === SDK.targetManager.mainTarget())
+      this._initConsoleMessages(target);
     this._viewport.invalidate();
   }
 
diff --git a/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js b/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
index fe8d988..5244640 100644
--- a/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/network/NetworkPanel.js
@@ -671,8 +671,10 @@
    * @param {!PerfUI.FilmStripView} filmStripView
    */
   constructor(timeCalculator, filmStripView) {
-    /** @type {?SDK.Target} */
-    this._target = null;
+    /** @type {?SDK.TracingManager} */
+    this._tracingManager = null;
+    /** @type {?SDK.ResourceTreeModel} */
+    this._resourceTreeModel = null;
     this._timeCalculator = timeCalculator;
     this._filmStripView = filmStripView;
   }
@@ -690,15 +692,15 @@
    * @override
    */
   tracingComplete() {
-    if (!this._tracingModel || !this._target)
+    if (!this._tracingModel || !this._tracingManager)
       return;
     this._tracingModel.tracingComplete();
-    var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(this._target);
-    this._target = null;
+    this._tracingManager = null;
     this._callback(new SDK.FilmStripModel(this._tracingModel, this._timeCalculator.minimumBoundary() * 1000));
     delete this._callback;
-    if (resourceTreeModel)
-      resourceTreeModel.resumeReload();
+    if (this._resourceTreeModel)
+      this._resourceTreeModel.resumeReload();
+    this._resourceTreeModel = null;
   }
 
   /**
@@ -717,35 +719,36 @@
   startRecording() {
     this._filmStripView.reset();
     this._filmStripView.setStatusText(Common.UIString('Recording frames...'));
-    if (this._target)
+    var tracingManagers = SDK.targetManager.models(SDK.TracingManager);
+    if (this._tracingManager || !tracingManagers.length)
       return;
 
-    this._target = SDK.targetManager.mainTarget();
+    this._tracingManager = tracingManagers[0];
+    this._resourceTreeModel = this._tracingManager.target().model(SDK.ResourceTreeModel);
     if (this._tracingModel)
       this._tracingModel.reset();
     else
       this._tracingModel = new SDK.TracingModel(new Bindings.TempFileBackingStorage('tracing'));
-    this._target.tracingManager.start(this, '-*,disabled-by-default-devtools.screenshot', '');
+    this._tracingManager.start(this, '-*,disabled-by-default-devtools.screenshot', '');
   }
 
   /**
    * @return {boolean}
    */
   isRecording() {
-    return !!this._target;
+    return !!this._tracingManager;
   }
 
   /**
    * @param {function(?SDK.FilmStripModel)} callback
    */
   stopRecording(callback) {
-    if (!this._target)
+    if (!this._tracingManager)
       return;
 
-    this._target.tracingManager.stop();
-    var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(this._target);
-    if (resourceTreeModel)
-      resourceTreeModel.suspendReload();
+    this._tracingManager.stop();
+    if (this._resourceTreeModel)
+      this._resourceTreeModel.suspendReload();
     this._callback = callback;
     this._filmStripView.setStatusText(Common.UIString('Fetching frames...'));
   }
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 cc2234f..31a94d7 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
@@ -32,20 +32,18 @@
     }
     const isArrayOrTypedArray = preview.subtype === 'array' || preview.subtype === 'typedarray';
     if (description) {
-      if (previewExperimentEnabled) {
-        // Hide the description for plain objects and plain arrays.
-        const plainObjectDescription = 'Object';
-        const size = SDK.RemoteObject.arrayLength(preview) || SDK.RemoteObject.mapOrSetEntriesCount(preview);
-        var text = preview.subtype === 'typedarray' ? SDK.RemoteObject.arrayNameFromDescription(description) : '';
-        if (isArrayOrTypedArray)
-          text += size > 1 ? ('(' + size + ')') : '';
-        else
-          text = description === plainObjectDescription ? '' : description;
-        if (text.length > 0)
-          parentElement.createChild('span', 'object-description').textContent = text + ' ';
-      } else if (preview.subtype !== 'array') {
-        parentElement.createTextChildren(description, ' ');
+      var text;
+      if (isArrayOrTypedArray) {
+        var arrayLength = SDK.RemoteObject.arrayLength(preview);
+        var arrayLengthText = arrayLength > 1 ? ('(' + arrayLength + ')') : '';
+        var arrayName = preview.subtype === 'typedarray' ? SDK.RemoteObject.arrayNameFromDescription(description) : '';
+        text = arrayName + arrayLengthText;
+      } else {
+        var hideDescription = previewExperimentEnabled && description === 'Object';
+        text = hideDescription ? '' : description;
       }
+      if (text.length > 0)
+        parentElement.createChild('span', 'object-description').textContent = text + ' ';
     }
 
     parentElement.createTextChild(isArrayOrTypedArray ? '[' : '{');
diff --git a/third_party/WebKit/Source/devtools/front_end/object_ui/objectValue.css b/third_party/WebKit/Source/devtools/front_end/object_ui/objectValue.css
index cfd403e..f1c6b53 100644
--- a/third_party/WebKit/Source/devtools/front_end/object_ui/objectValue.css
+++ b/third_party/WebKit/Source/devtools/front_end/object_ui/objectValue.css
@@ -99,6 +99,6 @@
     color: hsl(252, 100%, 75%);
 }
 
-.object-description {
+.object-properties-section .object-description {
     color: gray;
 }
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/Target.js b/third_party/WebKit/Source/devtools/front_end/sdk/Target.js
index 222c5b6..daf25f7 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/Target.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/Target.js
@@ -186,17 +186,18 @@
  * @enum {number}
  */
 SDK.Target.Capability = {
-  Browser: 1,
-  DOM: 2,
-  JS: 4,
-  Log: 8,
-  Network: 16,
-  Target: 32,
-  ScreenCapture: 64,
+  Browser: 1 << 0,
+  DOM: 1 << 1,
+  JS: 1 << 2,
+  Log: 1 << 3,
+  Network: 1 << 4,
+  Target: 1 << 5,
+  ScreenCapture: 1 << 6,
+  Tracing: 1 << 7,
 
   None: 0,
 
-  AllForTests: 127
+  AllForTests: (1 << 8) - 1
 };
 
 /**
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js b/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js
index 0cf6e752..52f19551 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/TargetManager.js
@@ -258,9 +258,6 @@
     target.model(SDK.DOMModel);
     target.model(SDK.CSSModel);
     target.model(SDK.CPUProfilerModel);
-
-    target.tracingManager = new SDK.TracingManager(target);
-
     target.model(SDK.ServiceWorkerManager);
 
     if (target.hasTargetCapability())
@@ -406,7 +403,7 @@
 
     var capabilities = SDK.Target.Capability.Browser | SDK.Target.Capability.DOM | SDK.Target.Capability.JS |
         SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target |
-        SDK.Target.Capability.ScreenCapture;
+        SDK.Target.Capability.ScreenCapture | SDK.Target.Capability.Tracing;
     if (Runtime.queryParam('isSharedWorker')) {
       capabilities = SDK.Target.Capability.Browser | SDK.Target.Capability.Log | SDK.Target.Capability.Network |
           SDK.Target.Capability.Target;
@@ -520,7 +517,8 @@
       return SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target;
     if (type === 'iframe') {
       return SDK.Target.Capability.Browser | SDK.Target.Capability.DOM | SDK.Target.Capability.JS |
-          SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target;
+          SDK.Target.Capability.Log | SDK.Target.Capability.Network | SDK.Target.Capability.Target |
+          SDK.Target.Capability.Tracing;
     }
     if (type === 'node')
       return SDK.Target.Capability.JS;
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/TracingManager.js b/third_party/WebKit/Source/devtools/front_end/sdk/TracingManager.js
index 06f4e03e..9e7af8e 100644
--- a/third_party/WebKit/Source/devtools/front_end/sdk/TracingManager.js
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/TracingManager.js
@@ -27,12 +27,13 @@
 /**
  * @unrestricted
  */
-SDK.TracingManager = class {
+SDK.TracingManager = class extends SDK.SDKModel {
   /**
    * @param {!SDK.Target} target
    */
   constructor(target) {
-    this._target = target;
+    super(target);
+    this._tracingAgent = target.tracingAgent();
     target.registerTracingDispatcher(new SDK.TracingDispatcher(this));
 
     /** @type {?SDK.TracingManagerClient} */
@@ -42,13 +43,6 @@
   }
 
   /**
-   * @return {?SDK.Target}
-   */
-  target() {
-    return this._target;
-  }
-
-  /**
    * @param {number=} usage
    * @param {number=} eventCount
    * @param {number=} percentFull
@@ -90,7 +84,7 @@
       throw new Error('Tracing is already started');
     var bufferUsageReportingIntervalMs = 500;
     this._activeClient = client;
-    return this._target.tracingAgent().start(
+    return this._tracingAgent.start(
         categoryFilter, options, bufferUsageReportingIntervalMs, SDK.TracingManager.TransferMode.ReportEvents);
   }
 
@@ -100,10 +94,12 @@
     if (this._finishing)
       throw new Error('Tracing is already being stopped');
     this._finishing = true;
-    this._target.tracingAgent().end();
+    this._tracingAgent.end();
   }
 };
 
+SDK.SDKModel.register(SDK.TracingManager, SDK.Target.Capability.Tracing);
+
 /** @typedef {!{
         cat: string,
         pid: number,
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineController.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineController.js
index 80e6965..dbfd06d 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineController.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineController.js
@@ -9,19 +9,19 @@
  */
 Timeline.TimelineController = class {
   /**
-   * @param {!SDK.Target} target
+   * @param {!SDK.TracingManager} tracingManager
    * @param {!Timeline.PerformanceModel} performanceModel
    * @param {!Timeline.TimelineController.Client} client
    */
-  constructor(target, performanceModel, client) {
-    this._target = target;
+  constructor(tracingManager, performanceModel, client) {
+    this._tracingManager = tracingManager;
     this._performanceModel = performanceModel;
     this._client = client;
 
     this._tracingModelBackingStorage = new Bindings.TempFileBackingStorage('tracing');
     this._tracingModel = new SDK.TracingModel(this._tracingModelBackingStorage);
 
-    this._performanceModel.setMainTarget(target);
+    this._performanceModel.setMainTarget(tracingManager.target());
 
     /** @type {!Array<!Timeline.ExtensionTracingSession>} */
     this._extensionSessions = [];
@@ -80,7 +80,7 @@
     var tracingStoppedPromises = [];
     tracingStoppedPromises.push(new Promise(resolve => this._tracingCompleteCallback = resolve));
     tracingStoppedPromises.push(this._stopProfilingOnAllModels());
-    this._target.tracingManager.stop();
+    this._tracingManager.stop();
     tracingStoppedPromises.push(SDK.targetManager.resumeAllTargets());
 
     this._client.loadingStarted();
@@ -163,8 +163,7 @@
         Promise.resolve();
     var samplingFrequencyHz = Common.moduleSetting('highResolutionCpuProfiling').get() ? 10000 : 1000;
     var options = 'sampling-frequency=' + samplingFrequencyHz;
-    var tracingManager = this._target.tracingManager;
-    return profilingStartedPromise.then(() => tracingManager.start(this, categories, options));
+    return profilingStartedPromise.then(() => this._tracingManager.start(this, categories, options));
   }
 
   /**
@@ -226,16 +225,13 @@
       return;
 
     var pid = mainMetaEvent.thread.process().id();
-    var mainCpuProfile = this._cpuProfiles.get(this._target.id());
+    var mainCpuProfile = this._cpuProfiles.get(this._tracingManager.target().id());
     this._injectCpuProfileEvent(pid, mainMetaEvent.thread.id(), mainCpuProfile);
 
     var workerMetaEvents = metadataEvents.filter(event => event.name === metadataEventTypes.TracingSessionIdForWorker);
     for (var metaEvent of workerMetaEvents) {
       var workerId = metaEvent.args['data']['workerId'];
-      var workerTarget = SDK.targetManager.targetById(workerId);
-      if (!workerTarget)
-        continue;
-      var cpuProfile = this._cpuProfiles.get(workerTarget.id());
+      var cpuProfile = this._cpuProfiles.get(workerId);
       this._injectCpuProfileEvent(
           metaEvent.thread.process().id(), metaEvent.args['data']['workerThreadId'], cpuProfile);
     }
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartView.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartView.js
index 82fa8a6..01a9b47 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartView.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelineFlameChartView.js
@@ -2,98 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-Timeline.FlameChartStyle = {
-  textColor: '#333'
-};
-
-/**
- * @enum {symbol}
- */
-Timeline.TimelineFlameChartEntryType = {
-  Frame: Symbol('Frame'),
-  Event: Symbol('Event'),
-  InteractionRecord: Symbol('InteractionRecord'),
-  ExtensionEvent: Symbol('ExtensionEvent')
-};
-
-/**
- * @implements {PerfUI.FlameChartMarker}
- * @unrestricted
- */
-Timeline.TimelineFlameChartMarker = class {
-  /**
-   * @param {number} startTime
-   * @param {number} startOffset
-   * @param {!Timeline.TimelineMarkerStyle} style
-   */
-  constructor(startTime, startOffset, style) {
-    this._startTime = startTime;
-    this._startOffset = startOffset;
-    this._style = style;
-  }
-
-  /**
-   * @override
-   * @return {number}
-   */
-  startTime() {
-    return this._startTime;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  color() {
-    return this._style.color;
-  }
-
-  /**
-   * @override
-   * @return {string}
-   */
-  title() {
-    var startTime = Number.millisToString(this._startOffset);
-    return Common.UIString('%s at %s', this._style.title, startTime);
-  }
-
-  /**
-   * @override
-   * @param {!CanvasRenderingContext2D} context
-   * @param {number} x
-   * @param {number} height
-   * @param {number} pixelsPerMillisecond
-   */
-  draw(context, x, height, pixelsPerMillisecond) {
-    var lowPriorityVisibilityThresholdInPixelsPerMs = 4;
-
-    if (this._style.lowPriority && pixelsPerMillisecond < lowPriorityVisibilityThresholdInPixelsPerMs)
-      return;
-    context.save();
-
-    if (!this._style.lowPriority) {
-      context.strokeStyle = this._style.color;
-      context.lineWidth = 2;
-      context.beginPath();
-      context.moveTo(x, 0);
-      context.lineTo(x, height);
-      context.stroke();
-    }
-
-    if (this._style.tall) {
-      context.strokeStyle = this._style.color;
-      context.lineWidth = this._style.lineWidth;
-      context.translate(this._style.lineWidth < 1 || (this._style.lineWidth & 1) ? 0.5 : 0, 0.5);
-      context.beginPath();
-      context.moveTo(x, height);
-      context.setLineDash(this._style.dashStyle);
-      context.lineTo(x, context.canvas.height);
-      context.stroke();
-    }
-    context.restore();
-  }
-};
-
 /**
  * @implements {Timeline.TimelineModeView}
  * @implements {PerfUI.FlameChartDelegate}
@@ -115,47 +23,56 @@
     this._searchResults;
     this._filters = filters;
 
-    this._splitWidget = new UI.SplitWidget(false, false, 'timelineFlamechartMainView', 150);
+    this._showMemoryGraphSetting = Common.settings.createSetting('timelineShowMemory', false);
 
-    this._dataProvider = new Timeline.TimelineFlameChartDataProvider(filters);
+    // Create main and network flamecharts.
+    this._networkSplitWidget = new UI.SplitWidget(false, false, 'timelineFlamechartMainView', 150);
+
     var mainViewGroupExpansionSetting = Common.settings.createSetting('timelineFlamechartMainViewGroupExpansion', {});
-    this._mainView = new PerfUI.FlameChart(this._dataProvider, this, mainViewGroupExpansionSetting);
-    this._mainView.alwaysShowVerticalScroll();
-    this._mainView.enableRuler(false);
+    this._mainDataProvider = new Timeline.TimelineFlameChartDataProvider(filters);
+    this._mainFlameChart = new PerfUI.FlameChart(this._mainDataProvider, this, mainViewGroupExpansionSetting);
+    this._mainFlameChart.alwaysShowVerticalScroll();
+    this._mainFlameChart.enableRuler(false);
 
-    this._networkViewGroupExpansionSetting =
+    this._networkFlameChartGroupExpansionSetting =
         Common.settings.createSetting('timelineFlamechartNetworkViewGroupExpansion', {});
     this._networkDataProvider = new Timeline.TimelineFlameChartNetworkDataProvider();
-    this._networkView = new PerfUI.FlameChart(this._networkDataProvider, this, this._networkViewGroupExpansionSetting);
-    this._networkView.alwaysShowVerticalScroll();
+    this._networkFlameChart = new PerfUI.FlameChart(
+        this._networkDataProvider, this, this._networkFlameChartGroupExpansionSetting);
+    this._networkFlameChart.alwaysShowVerticalScroll();
 
     this._networkPane = new UI.VBox();
     this._networkPane.setMinimumSize(23, 23);
-    this._networkView.show(this._networkPane.element);
+    this._networkFlameChart.show(this._networkPane.element);
     this._splitResizer = this._networkPane.element.createChild('div', 'timeline-flamechart-resizer');
-    this._splitWidget.hideDefaultResizer(true);
-    this._splitWidget.installResizer(this._splitResizer);
+    this._networkSplitWidget.hideDefaultResizer(true);
+    this._networkSplitWidget.installResizer(this._splitResizer);
 
-    this._splitWidget.setMainWidget(this._mainView);
-    this._splitWidget.setSidebarWidget(this._networkPane);
+    this._networkSplitWidget.setMainWidget(this._mainFlameChart);
+    this._networkSplitWidget.setSidebarWidget(this._networkPane);
 
-    if (Runtime.experiments.isEnabled('timelineMultipleMainViews')) {
-      // Create top level properties splitter.
-      this._detailsSplitWidget = new UI.SplitWidget(false, true, 'timelinePanelDetailsSplitViewState');
-      this._detailsSplitWidget.element.classList.add('timeline-details-split');
-      this._detailsView = new Timeline.TimelineDetailsView(filters, delegate);
-      this._detailsSplitWidget.installResizer(this._detailsView.headerElement());
-      this._detailsSplitWidget.setMainWidget(this._splitWidget);
-      this._detailsSplitWidget.setSidebarWidget(this._detailsView);
-      this._detailsSplitWidget.show(this.element);
-    } else {
-      this._splitWidget.show(this.element);
-    }
+    // Create counters chart splitter.
+    this._chartSplitWidget = new UI.SplitWidget(false, true, 'timelineCountersSplitViewState');
+    this._countersView = new Timeline.CountersGraph(this._delegate);
+    this._chartSplitWidget.setMainWidget(this._networkSplitWidget);
+    this._chartSplitWidget.setSidebarWidget(this._countersView);
+    this._chartSplitWidget.hideDefaultResizer();
+    this._chartSplitWidget.installResizer(/** @type {!Element} */ (this._countersView.resizerElement()));
+    this._updateCountersGraphToggle();
 
-    this._onMainEntrySelected = this._onEntrySelected.bind(this, this._dataProvider);
+    // Create top level properties splitter.
+    this._detailsSplitWidget = new UI.SplitWidget(false, true, 'timelinePanelDetailsSplitViewState');
+    this._detailsSplitWidget.element.classList.add('timeline-details-split');
+    this._detailsView = new Timeline.TimelineDetailsView(filters, delegate);
+    this._detailsSplitWidget.installResizer(this._detailsView.headerElement());
+    this._detailsSplitWidget.setMainWidget(this._chartSplitWidget);
+    this._detailsSplitWidget.setSidebarWidget(this._detailsView);
+    this._detailsSplitWidget.show(this.element);
+
+    this._onMainEntrySelected = this._onEntrySelected.bind(this, this._mainDataProvider);
     this._onNetworkEntrySelected = this._onEntrySelected.bind(this, this._networkDataProvider);
-    this._mainView.addEventListener(PerfUI.FlameChart.Events.EntrySelected, this._onMainEntrySelected, this);
-    this._networkView.addEventListener(PerfUI.FlameChart.Events.EntrySelected, this._onNetworkEntrySelected, this);
+    this._mainFlameChart.addEventListener(PerfUI.FlameChart.Events.EntrySelected, this._onMainEntrySelected, this);
+    this._networkFlameChart.addEventListener(PerfUI.FlameChart.Events.EntrySelected, this._onNetworkEntrySelected, this);
     this._nextExtensionIndex = 0;
 
     this._boundRefresh = this._refresh.bind(this);
@@ -203,8 +120,9 @@
   }
 
   _refresh() {
-    this._dataProvider.setModel(this._model);
+    this._mainDataProvider.setModel(this._model);
     this._networkDataProvider.setModel(this._model);
+    this._countersView.setModel(this._model);
     if (this._detailsView)
       this._detailsView.setModel(this._model);
 
@@ -212,15 +130,15 @@
     this._appendExtensionData();
 
     if (this._networkDataProvider.isEmpty()) {
-      this._mainView.enableRuler(true);
-      this._splitWidget.hideSidebar();
+      this._mainFlameChart.enableRuler(true);
+      this._networkSplitWidget.hideSidebar();
     } else {
-      this._mainView.enableRuler(false);
-      this._splitWidget.showBoth();
+      this._mainFlameChart.enableRuler(false);
+      this._networkSplitWidget.showBoth();
       this.resizeToPreferredHeights();
     }
-    this._mainView.reset();
-    this._networkView.reset();
+    this._mainFlameChart.reset();
+    this._networkFlameChart.reset();
   }
 
   _appendExtensionData() {
@@ -228,8 +146,8 @@
       return;
     var extensions = this._model.extensionInfo();
     while (this._nextExtensionIndex < extensions.length)
-      this._dataProvider.appendExtensionEvents(extensions[this._nextExtensionIndex++]);
-    this._mainView.scheduleUpdate();
+      this._mainDataProvider.appendExtensionEvents(extensions[this._nextExtensionIndex++]);
+    this._mainFlameChart.scheduleUpdate();
   }
 
   /**
@@ -238,18 +156,19 @@
    */
   highlightEvent(event) {
     var entryIndex =
-        event ? this._dataProvider.entryIndexForSelection(Timeline.TimelineSelection.fromTraceEvent(event)) : -1;
+        event ? this._mainDataProvider.entryIndexForSelection(Timeline.TimelineSelection.fromTraceEvent(event)) : -1;
     if (entryIndex >= 0)
-      this._mainView.highlightEntry(entryIndex);
+      this._mainFlameChart.highlightEntry(entryIndex);
     else
-      this._mainView.hideHighlight();
+      this._mainFlameChart.hideHighlight();
   }
 
   /**
    * @override
    */
   willHide() {
-    this._networkViewGroupExpansionSetting.removeChangeListener(this.resizeToPreferredHeights, this);
+    this._networkFlameChartGroupExpansionSetting.removeChangeListener(this.resizeToPreferredHeights, this);
+    this._showMemoryGraphSetting.removeChangeListener(this._updateCountersGraphToggle, this);
     Bindings.blackboxManager.removeChangeListener(this._boundRefresh);
   }
 
@@ -257,12 +176,20 @@
    * @override
    */
   wasShown() {
-    this._networkViewGroupExpansionSetting.addChangeListener(this.resizeToPreferredHeights, this);
+    this._networkFlameChartGroupExpansionSetting.addChangeListener(this.resizeToPreferredHeights, this);
+    this._showMemoryGraphSetting.addChangeListener(this._updateCountersGraphToggle, this);
     Bindings.blackboxManager.addChangeListener(this._boundRefresh);
     if (this._needsResizeToPreferredHeights)
       this.resizeToPreferredHeights();
-    this._mainView.scheduleUpdate();
-    this._networkView.scheduleUpdate();
+    this._mainFlameChart.scheduleUpdate();
+    this._networkFlameChart.scheduleUpdate();
+  }
+
+  _updateCountersGraphToggle() {
+    if (this._showMemoryGraphSetting.get())
+      this._chartSplitWidget.showBoth();
+    else
+      this._chartSplitWidget.hideSidebar();
   }
 
   /**
@@ -279,9 +206,10 @@
    * @param {number} endTime
    */
   setWindowTimes(startTime, endTime) {
-    this._mainView.setWindowTimes(startTime, endTime);
-    this._networkView.setWindowTimes(startTime, endTime);
+    this._mainFlameChart.setWindowTimes(startTime, endTime);
+    this._networkFlameChart.setWindowTimes(startTime, endTime);
     this._networkDataProvider.setWindowTimes(startTime, endTime);
+    this._countersView.setWindowTimes(startTime, endTime);
     this._windowStartTime = startTime;
     this._windowEndTime = endTime;
   }
@@ -296,7 +224,7 @@
       this._delegate.select(null);
       return;
     }
-    var timelineSelection = this._dataProvider.selectionForEvent(event);
+    var timelineSelection = this._mainDataProvider.selectionForEvent(event);
     if (timelineSelection)
       this._delegate.select(timelineSelection);
   }
@@ -306,10 +234,10 @@
    * @param {?Timeline.TimelineSelection} selection
    */
   setSelection(selection) {
-    var index = this._dataProvider.entryIndexForSelection(selection);
-    this._mainView.setSelectedEntry(index);
+    var index = this._mainDataProvider.entryIndexForSelection(selection);
+    this._mainFlameChart.setSelectedEntry(index);
     index = this._networkDataProvider.entryIndexForSelection(selection);
-    this._networkView.setSelectedEntry(index);
+    this._networkFlameChart.setSelectedEntry(index);
     if (selection && this._detailsView)
       this._detailsView.setSelection(selection);
   }
@@ -331,7 +259,7 @@
     this._needsResizeToPreferredHeights = false;
     this._networkPane.element.classList.toggle(
         'timeline-network-resizer-disabled', !this._networkDataProvider.isExpanded());
-    this._splitWidget.setSidebarSize(
+    this._networkSplitWidget.setSidebarSize(
         this._networkDataProvider.preferredHeight() + this._splitResizer.clientHeight + PerfUI.FlameChart.HeaderHeight +
         2);
   }
@@ -488,3 +416,95 @@
     this.entryIndex = entryIndex;
   }
 };
+
+Timeline.FlameChartStyle = {
+  textColor: '#333'
+};
+
+/**
+ * @enum {symbol}
+ */
+Timeline.TimelineFlameChartEntryType = {
+  Frame: Symbol('Frame'),
+  Event: Symbol('Event'),
+  InteractionRecord: Symbol('InteractionRecord'),
+  ExtensionEvent: Symbol('ExtensionEvent')
+};
+
+/**
+ * @implements {PerfUI.FlameChartMarker}
+ * @unrestricted
+ */
+Timeline.TimelineFlameChartMarker = class {
+  /**
+   * @param {number} startTime
+   * @param {number} startOffset
+   * @param {!Timeline.TimelineMarkerStyle} style
+   */
+  constructor(startTime, startOffset, style) {
+    this._startTime = startTime;
+    this._startOffset = startOffset;
+    this._style = style;
+  }
+
+  /**
+   * @override
+   * @return {number}
+   */
+  startTime() {
+    return this._startTime;
+  }
+
+  /**
+   * @override
+   * @return {string}
+   */
+  color() {
+    return this._style.color;
+  }
+
+  /**
+   * @override
+   * @return {string}
+   */
+  title() {
+    var startTime = Number.millisToString(this._startOffset);
+    return Common.UIString('%s at %s', this._style.title, startTime);
+  }
+
+  /**
+   * @override
+   * @param {!CanvasRenderingContext2D} context
+   * @param {number} x
+   * @param {number} height
+   * @param {number} pixelsPerMillisecond
+   */
+  draw(context, x, height, pixelsPerMillisecond) {
+    var lowPriorityVisibilityThresholdInPixelsPerMs = 4;
+
+    if (this._style.lowPriority && pixelsPerMillisecond < lowPriorityVisibilityThresholdInPixelsPerMs)
+      return;
+    context.save();
+
+    if (!this._style.lowPriority) {
+      context.strokeStyle = this._style.color;
+      context.lineWidth = 2;
+      context.beginPath();
+      context.moveTo(x, 0);
+      context.lineTo(x, height);
+      context.stroke();
+    }
+
+    if (this._style.tall) {
+      context.strokeStyle = this._style.color;
+      context.lineWidth = this._style.lineWidth;
+      context.translate(this._style.lineWidth < 1 || (this._style.lineWidth & 1) ? 0.5 : 0, 0.5);
+      context.beginPath();
+      context.moveTo(x, height);
+      context.setLineDash(this._style.dashStyle);
+      context.lineTo(x, context.canvas.height);
+      context.stroke();
+    }
+    context.restore();
+  }
+};
diff --git a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
index c660d14..ee00e52 100644
--- a/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
+++ b/third_party/WebKit/Source/devtools/front_end/timeline/TimelinePanel.js
@@ -66,9 +66,6 @@
 
     this._cpuThrottlingManager = new Components.CPUThrottlingManager();
 
-    /** @type {!Array<!Timeline.TimelineModeView>} */
-    this._currentViews = [];
-
     this._viewModeSetting =
         Common.settings.createSetting('timelineViewMode', Timeline.TimelinePanel.ViewMode.FlameChart);
 
@@ -108,11 +105,8 @@
     SDK.targetManager.addEventListener(SDK.TargetManager.Events.PageReloadRequested, this._pageReloadRequested, this);
     SDK.targetManager.addEventListener(SDK.TargetManager.Events.Load, this._loadEventFired, this);
 
-    this._stackView = new UI.StackView(false);
-    this._stackView.element.classList.add('timeline-view-stack');
-
     if (Runtime.experiments.isEnabled('timelineMultipleMainViews')) {
-      const viewMode = Timeline.TimelinePanel.ViewMode;
+      var viewMode = Timeline.TimelinePanel.ViewMode;
       this._tabbedPane = new UI.TabbedPane();
       this._tabbedPane.appendTab(viewMode.FlameChart, Common.UIString('Flame Chart'), new UI.VBox());
       this._tabbedPane.appendTab(viewMode.BottomUp, Common.UIString('Bottom-Up'), new UI.VBox());
@@ -120,16 +114,6 @@
       this._tabbedPane.appendTab(viewMode.EventLog, Common.UIString('Event Log'), new UI.VBox());
       this._tabbedPane.addEventListener(UI.TabbedPane.Events.TabSelected, this._onMainViewChanged.bind(this));
       this._tabbedPane.selectTab(this._viewModeSetting.get());
-    } else {
-      // Create top level properties splitter.
-      this._detailsSplitWidget = new UI.SplitWidget(false, true, 'timelinePanelDetailsSplitViewState', 400);
-      this._detailsSplitWidget.element.classList.add('timeline-details-split');
-      this._detailsView = new Timeline.TimelineDetailsView(this._filters, this);
-      this._detailsSplitWidget.installResizer(this._detailsView.headerElement());
-      this._detailsSplitWidget.setSidebarWidget(this._detailsView);
-      this._detailsSplitWidget.setMainWidget(this._stackView);
-      this._detailsSplitWidget.hideSidebar();
-      this._detailsSplitWidget.show(this._timelinePane.element);
     }
 
     this._onModeChanged();
@@ -179,9 +163,7 @@
   _onWindowChanged(event) {
     this._windowStartTime = event.data.startTime;
     this._windowEndTime = event.data.endTime;
-
-    for (var i = 0; i < this._currentViews.length; ++i)
-      this._currentViews[i].setWindowTimes(this._windowStartTime, this._windowEndTime);
+    this._currentView.setWindowTimes(this._windowStartTime, this._windowEndTime);
 
     if (!this._selection || this._selection.type() === Timeline.TimelineSelection.Type.Range)
       this.select(null);
@@ -210,27 +192,6 @@
   }
 
   /**
-   * @param {!Timeline.TimelineModeView} modeView
-   */
-  _addModeView(modeView) {
-    modeView.setModel(this._performanceModel);
-    modeView.setWindowTimes(this._windowStartTime, this._windowEndTime);
-    var splitWidget =
-        this._stackView.appendView(modeView.view(), 'timelinePanelTimelineStackSplitViewState', undefined, 112);
-    var resizer = modeView.resizerElement();
-    if (splitWidget && resizer) {
-      splitWidget.hideDefaultResizer();
-      splitWidget.installResizer(resizer);
-    }
-    this._currentViews.push(modeView);
-  }
-
-  _removeAllModeViews() {
-    this._currentViews = [];
-    this._stackView.detachChildWidgets();
-  }
-
-  /**
    * @param {!Timeline.TimelinePanel.State} state
    */
   _setState(state) {
@@ -432,8 +393,6 @@
   }
 
   _onModeChanged() {
-    const showMemory = this._showMemorySetting.get();
-    const showScreenshots = this._showScreenshotsSetting.get();
     // Set up overview controls.
     this._overviewControls = [];
     this._overviewControls.push(new Timeline.TimelineEventOverviewResponsiveness());
@@ -442,31 +401,26 @@
     this._overviewControls.push(new Timeline.TimelineEventOverviewFrames());
     this._overviewControls.push(new Timeline.TimelineEventOverviewCPUActivity());
     this._overviewControls.push(new Timeline.TimelineEventOverviewNetwork());
-    if (showScreenshots)
+    if (this._showScreenshotsSetting.get())
       this._overviewControls.push(new Timeline.TimelineFilmStripOverview());
-    if (showMemory)
+    if (this._showMemorySetting.get())
       this._overviewControls.push(new Timeline.TimelineEventOverviewMemory());
     for (var control of this._overviewControls)
       control.setModel(this._performanceModel);
     this._overviewPane.setOverviewControls(this._overviewControls);
 
-    // Set up the main view.
-    this._removeAllModeViews();
-
-    var viewMode = Timeline.TimelinePanel.ViewMode.FlameChart;
+    // Set up main view.
+    if (this._currentView)
+      this._currentView.detach();
+    var viewMode = Runtime.experiments.isEnabled('timelineMultipleMainViews')
+        ? this._tabbedPane.selectedTabId
+        : Timeline.TimelinePanel.ViewMode.FlameChart;
     this._flameChart = null;
-    if (Runtime.experiments.isEnabled('timelineMultipleMainViews')) {
-      viewMode = this._tabbedPane.selectedTabId;
-      this._stackView.detach();
-      this._stackView.show(this._tabbedPane.visibleView.element);
-    }
     var mainView;
     if (viewMode === Timeline.TimelinePanel.ViewMode.FlameChart) {
       this._flameChart = new Timeline.TimelineFlameChartView(this, this._filters);
-      this._addModeView(this._flameChart);
-      if (showMemory)
-        this._addModeView(new Timeline.CountersGraph(this));
       mainView = this._flameChart;
+      this._currentView = this._flameChart;
     } else {
       switch (viewMode) {
         case Timeline.TimelinePanel.ViewMode.CallTree:
@@ -480,15 +434,23 @@
           break;
       }
       var treeView = new Timeline.TimelineTreeModeView(this, mainView);
-      this._addModeView(treeView);
+      this._currentView = treeView;
     }
+    this._currentView.setModel(this._performanceModel);
+    this._currentView.setWindowTimes(this._windowStartTime, this._windowEndTime);
     if (this._searchableView)
       this._searchableView.detach();
     this._searchableView = new UI.SearchableView(mainView);
     this._searchableView.setMinimumSize(0, 100);
     this._searchableView.element.classList.add('searchable-view');
     this._searchableView.show(this._timelinePane.element);
-    this._tabbedPane.show(this._searchableView.element);
+
+    if (Runtime.experiments.isEnabled('timelineMultipleMainViews')) {
+      this._tabbedPane.show(this._searchableView.element);
+      this._currentView.show(this._tabbedPane.visibleView.element);
+    } else {
+      this._currentView.show(this._searchableView.element);
+    }
     mainView.setSearchableView(this._searchableView);
     if (this._lastViewMode !== viewMode) {
       this._lastViewMode = viewMode;
@@ -544,8 +506,8 @@
    */
   _startRecording(userInitiated) {
     console.assert(!this._statusPane, 'Status pane is already opened.');
-    var mainTarget = SDK.targetManager.mainTarget();
-    if (!mainTarget)
+    var tracingManagers = SDK.targetManager.models(SDK.TracingManager);
+    if (!tracingManagers.length)
       return Promise.resolve();
     this._setState(Timeline.TimelinePanel.State.StartPending);
     this._showRecordingStarted();
@@ -561,7 +523,7 @@
     };
 
     this._pendingPerformanceModel = new Timeline.PerformanceModel();
-    this._controller = new Timeline.TimelineController(mainTarget, this._pendingPerformanceModel, this);
+    this._controller = new Timeline.TimelineController(tracingManagers[0], this._pendingPerformanceModel, this);
     Host.userMetrics.actionTaken(
         userInitiated ? Host.UserMetrics.Action.TimelineStarted : Host.UserMetrics.Action.TimelinePageReloadStarted);
     this._setUIControlsEnabled(false);
@@ -604,8 +566,6 @@
 
   _clear() {
     this._showLandingPage();
-    if (this._detailsSplitWidget)
-      this._detailsSplitWidget.hideSidebar();
     this._reset();
   }
 
@@ -622,7 +582,7 @@
     if (this._performanceModel)
       this._performanceModel.dispose();
     this._performanceModel = model;
-    this._currentViews.forEach(view => view.setModel(this._performanceModel));
+    this._currentView.setModel(model);
 
     this._overviewPane.reset();
     if (model) {
@@ -642,8 +602,6 @@
       this.requestWindowTimes(0, Infinity);
     }
     this._overviewPane.scheduleUpdate();
-    if (this._detailsView)
-      this._detailsView.setModel(model);
 
     this.select(null);
     if (this._flameChart)
@@ -790,9 +748,6 @@
     performanceModel.setTracingModel(tracingModel);
     this._backingStorage = backingStorage;
     this._setModel(performanceModel);
-
-    if (this._detailsSplitWidget)
-      this._detailsSplitWidget.showBoth();
   }
 
   _showRecordingStarted() {
@@ -898,12 +853,7 @@
     if (!selection)
       selection = Timeline.TimelineSelection.fromRange(this._windowStartTime, this._windowEndTime);
     this._selection = selection;
-    if (preferredTab && this._detailsView)
-      this._detailsView.setPreferredTab(preferredTab);
-    for (var view of this._currentViews)
-      view.setSelection(selection);
-    if (this._detailsView)
-      this._detailsView.setSelection(selection);
+    this._currentView.setSelection(selection);
   }
 
   /**
@@ -931,8 +881,7 @@
    * @param {?SDK.TracingModel.Event} event
    */
   highlightEvent(event) {
-    for (var view of this._currentViews)
-      view.highlightEvent(event);
+    this._currentView.highlightEvent(event);
   }
 
   /**
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/StackView.js b/third_party/WebKit/Source/devtools/front_end/ui/StackView.js
deleted file mode 100644
index 3230919..0000000
--- a/third_party/WebKit/Source/devtools/front_end/ui/StackView.js
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2014 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
- * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/**
- * @unrestricted
- */
-UI.StackView = class extends UI.VBox {
-  /**
-   * @param {boolean} isVertical
-   */
-  constructor(isVertical) {
-    super();
-    this._isVertical = isVertical;
-    this._currentSplitWidget = null;
-  }
-
-  /**
-   * @param {!UI.Widget} view
-   * @param {string=} sidebarSizeSettingName
-   * @param {number=} defaultSidebarWidth
-   * @param {number=} defaultSidebarHeight
-   * @return {?UI.SplitWidget}
-   */
-  appendView(view, sidebarSizeSettingName, defaultSidebarWidth, defaultSidebarHeight) {
-    var splitWidget =
-        new UI.SplitWidget(this._isVertical, true, sidebarSizeSettingName, defaultSidebarWidth, defaultSidebarHeight);
-    splitWidget.setMainWidget(view);
-    splitWidget.hideSidebar();
-
-    if (!this._currentSplitWidget) {
-      splitWidget.show(this.element);
-    } else {
-      this._currentSplitWidget.setSidebarWidget(splitWidget);
-      this._currentSplitWidget.showBoth();
-    }
-
-    var lastSplitWidget = this._currentSplitWidget;
-    this._currentSplitWidget = splitWidget;
-    return lastSplitWidget;
-  }
-
-  /**
-   * @override
-   */
-  detachChildWidgets() {
-    super.detachChildWidgets();
-    this._currentSplitWidget = null;
-  }
-};
diff --git a/third_party/WebKit/Source/devtools/front_end/ui/module.json b/third_party/WebKit/Source/devtools/front_end/ui/module.json
index 8a498d9..3cb2115 100644
--- a/third_party/WebKit/Source/devtools/front_end/ui/module.json
+++ b/third_party/WebKit/Source/devtools/front_end/ui/module.json
@@ -40,7 +40,6 @@
         "SettingsUI.js",
         "SoftContextMenu.js",
         "SplitWidget.js",
-        "StackView.js",
         "TextPrompt.js",
         "ThrottledWidget.js",
         "Toolbar.js",
diff --git a/third_party/WebKit/Source/devtools/package.json b/third_party/WebKit/Source/devtools/package.json
index 1e2519f..e55dd255 100644
--- a/third_party/WebKit/Source/devtools/package.json
+++ b/third_party/WebKit/Source/devtools/package.json
@@ -9,7 +9,7 @@
     "debug-test": "node scripts/npm_test.js --debug-devtools",
     "compat-test": "node scripts/npm_test.js --compat-protocol=1.2",
     "lint": "eslint front_end",
-    "format": "node scripts/format.js",
+    "format": "git cl format --js .",
     "closure": "python scripts/compile_frontend.py",
     "setup-dtrun": "cd scripts/devtools_run && npm link",
     "format-py": "yapf --exclude scripts/build/rjsmin.py -i --recursive scripts PRESUBMIT.py"
@@ -32,9 +32,6 @@
   },
   "homepage": "https://devtools.chrome.com",
   "devDependencies": {
-    "eslint": "3.10.0",
-    "clang-format": "1.0.45",
-    "async": "1.5.2",
-    "globby": "6.0.0"
+    "eslint": "3.10.0"
   }
 }
diff --git a/third_party/WebKit/Source/devtools/scripts/clang_format/index.js b/third_party/WebKit/Source/devtools/scripts/clang_format/index.js
deleted file mode 100644
index 866bfe7..0000000
--- a/third_party/WebKit/Source/devtools/scripts/clang_format/index.js
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/usr/bin/env node
-'use strict';
-
-var fs = require('fs');
-var os = require('os');
-var path = require('path');
-var spawn = require('child_process').spawn;
-var globby = require('globby');
-var async = require('async');
-
-var VERSION = '1.0.45';
-var LOCATION = __filename;
-var CLANG_FORMAT_NODE_MODULES_PATH = path.resolve(__dirname, '..', '..', 'node_modules', 'clang-format');
-
-/**
- * Start a child process running the native clang-format binary.
- * @param file a Vinyl virtual file reference
- * @param enc the encoding to use for reading stdout
- * @param style valid argument to clang-format's '-style' flag
- * @param done callback invoked when the child process terminates
- * @returns {Stream} the formatted code
- */
-function clangFormat(file, enc, style, done) {
-  var args = ['-style=' + style, file.path];
-  return spawnClangFormat(args, done, ['ignore', 'pipe', process.stderr]).stdout;
-}
-
-/**
- * Spawn the clang-format binary with given arguments.
- */
-function spawnClangFormat(args, done, stdio) {
-  // WARNING: This function's interface should stay stable across versions for the cross-version
-  // loading below to work.
-  if (args.indexOf('-version') !== -1 || args.indexOf('--version') !== -1) {
-    // Print our version.
-    // This makes it impossible to format files called '-version' or '--version'. That's a feature.
-    // minimist & Co don't support single dash args, which we need to match binary clang-format.
-    console.log('clang-format NPM version', VERSION, 'at', LOCATION);
-    process.exit(0);
-  }
-  var nativeBinary;
-  if (os.platform() === 'win32')
-    nativeBinary = CLANG_FORMAT_NODE_MODULES_PATH + '/bin/win32/clang-format.exe';
-  else
-    nativeBinary = CLANG_FORMAT_NODE_MODULES_PATH + '/bin/' + os.platform() + '_' + os.arch() + '/clang-format';
-
-  if (!fs.existsSync(nativeBinary)) {
-    message = 'FATAL: This module doesn\'t bundle the clang-format executable for your platform. ' +
-        '(' + os.platform() + '_' + os.arch() + ')\n' +
-        'Consider installing it with your native package manager instead.\n';
-    throw new Error(message);
-  }
-
-  // extract glob, if present
-  var globString = args.filter(function(arg) {
-                         return arg.indexOf('--glob=') === 0;
-                       })
-                       .map(function(arg) {
-                         return arg.replace('--glob=', '');
-                       })
-                       .shift();
-
-  // extract ignore, if present
-  var ignore = args.filter(function(arg) {
-                     return arg.indexOf('--ignore=') === 0;
-                   })
-                   .map(function(arg) {
-                     return arg.replace('--ignore=', '');
-                   })
-                   .shift();
-
-  if (globString) {
-    var globs = globString.split(',');
-    // remove glob and ignore from arg list
-    args = args.filter(function(arg) {
-                 return arg.indexOf('--glob=') === -1;
-               })
-               .filter(function(arg) {
-                 return arg.indexOf('--ignore=') === -1;
-               });
-
-    var options = {};
-    if (ignore)
-      options.ignore = ignore.split(',');
-
-
-    return globby(globs, options).then(function(files) {
-      // split file array into chunks of 30
-      var i, j, chunks = [], chunkSize = 30;
-      for (i = 0, j = files.length; i < j; i += chunkSize)
-        chunks.push(files.slice(i, i + chunkSize));
-
-
-      // launch a new process for each chunk
-      async.series(
-          chunks.map(function(chunk) {
-            return function(callback) {
-              var clangFormatProcess = spawn(nativeBinary, args.concat(chunk), {stdio: stdio});
-              clangFormatProcess.on('close', function(exit) {
-                if (exit !== 0)
-                  callback(exit);
-                else
-                  callback(null, exit);
-              });
-            };
-          }),
-          function(err, results) {
-            if (err)
-              done(err);
-            console.log('\n');
-            console.log('ran clang-format on', files.length, files.length === 1 ? 'file' : 'files');
-            done(results.shift() || 0);
-          });
-    });
-  } else {
-    var clangFormatProcess = spawn(nativeBinary, args, {stdio: stdio});
-    clangFormatProcess.on('close', function(exit) {
-      if (exit)
-        done(exit);
-    });
-    return clangFormatProcess;
-  }
-}
-
-function main() {
-  try {
-    // Pass all arguments to clang-format, including e.g. -version etc.
-    spawnClangFormat(process.argv.slice(2), process.exit, 'inherit');
-  } catch (e) {
-    process.stdout.write(e.message);
-    process.exit(1);
-  }
-}
-
-module.exports = clangFormat;
-module.exports.version = VERSION;
-module.exports.location = LOCATION;
-module.exports.spawnClangFormat = spawnClangFormat;
-
-if (require.main === module)
-  main();
diff --git a/third_party/WebKit/Source/devtools/scripts/format.js b/third_party/WebKit/Source/devtools/scripts/format.js
deleted file mode 100644
index 449d10e3..0000000
--- a/third_party/WebKit/Source/devtools/scripts/format.js
+++ /dev/null
@@ -1,28 +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.
-
-var childProcess = require('child_process');
-var fs = require('fs');
-var path = require('path');
-
-var args = process.argv.slice(2);
-
-var CLANG_FORMAT_PATH = path.resolve(__dirname, 'clang_format', 'index.js');
-var IGNORE_FILE_PATH = path.resolve(__dirname, '..', '.eslintignore');
-
-var ignoreFile = fs.readFileSync(IGNORE_FILE_PATH, 'utf-8');
-var ignores = ignoreFile.split('\n').filter(str => str.length);
-var ignoreArg = '--ignore=' + ignores.join(',');
-
-console.log('Running clang-format');
-var clangArgs = ['-i', ignoreArg];
-if (args.length)
-  clangArgs = clangArgs.concat(args);
-else
-  clangArgs.push('--glob=+(scripts|front_end)/**/*.js');
-
-
-var options = {cwd: path.resolve(__dirname, '..')};
-
-childProcess.fork(CLANG_FORMAT_PATH, clangArgs, options);
diff --git a/third_party/WebKit/Source/modules/quota/NavigatorStorageQuota.idl b/third_party/WebKit/Source/modules/quota/NavigatorStorageQuota.idl
index 09925e13..d69e46c 100644
--- a/third_party/WebKit/Source/modules/quota/NavigatorStorageQuota.idl
+++ b/third_party/WebKit/Source/modules/quota/NavigatorStorageQuota.idl
@@ -25,5 +25,5 @@
     [MeasureAs=PrefixedStorageQuota] readonly attribute DeprecatedStorageQuota webkitPersistentStorage;
 
     // https://storage.spec.whatwg.org/#api
-    [RuntimeEnabled=DurableStorage] readonly attribute StorageManager storage;
+    [SecureContext, RuntimeEnabled=DurableStorage] readonly attribute StorageManager storage;
 };
diff --git a/third_party/WebKit/Source/modules/quota/StorageManager.cpp b/third_party/WebKit/Source/modules/quota/StorageManager.cpp
index 2830ea3e..0341f5f 100644
--- a/third_party/WebKit/Source/modules/quota/StorageManager.cpp
+++ b/third_party/WebKit/Source/modules/quota/StorageManager.cpp
@@ -24,6 +24,9 @@
 
 namespace {
 
+const char uniqueOriginErrorMessage[] =
+    "The operation is not supported in this context.";
+
 class EstimateCallbacks final : public StorageQuotaCallbacks {
   WTF_MAKE_NONCOPYABLE(EstimateCallbacks);
 
@@ -60,19 +63,14 @@
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
   ScriptPromise promise = resolver->promise();
   ExecutionContext* executionContext = scriptState->getExecutionContext();
+  DCHECK(executionContext->isSecureContext());  // [SecureContext] in IDL
   SecurityOrigin* securityOrigin = executionContext->getSecurityOrigin();
-  // TODO(dgrogan): Is the isUnique() check covered by the later
-  // isSecureContext() check? If so, maybe remove it. Write a test if it
-  // stays.
   if (securityOrigin->isUnique()) {
-    resolver->reject(DOMException::create(NotSupportedError));
+    resolver->reject(V8ThrowException::createTypeError(
+        scriptState->isolate(), uniqueOriginErrorMessage));
     return promise;
   }
-  String errorMessage;
-  if (!executionContext->isSecureContext(errorMessage)) {
-    resolver->reject(DOMException::create(SecurityError, errorMessage));
-    return promise;
-  }
+
   ASSERT(executionContext->isDocument());
   PermissionService* permissionService =
       getPermissionService(scriptState->getExecutionContext());
@@ -96,6 +94,15 @@
 ScriptPromise StorageManager::persisted(ScriptState* scriptState) {
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
   ScriptPromise promise = resolver->promise();
+  ExecutionContext* executionContext = scriptState->getExecutionContext();
+  DCHECK(executionContext->isSecureContext());  // [SecureContext] in IDL
+  SecurityOrigin* securityOrigin = executionContext->getSecurityOrigin();
+  if (securityOrigin->isUnique()) {
+    resolver->reject(V8ThrowException::createTypeError(
+        scriptState->isolate(), uniqueOriginErrorMessage));
+    return promise;
+  }
+
   PermissionService* permissionService =
       getPermissionService(scriptState->getExecutionContext());
   if (!permissionService) {
@@ -117,15 +124,11 @@
   ScriptPromiseResolver* resolver = ScriptPromiseResolver::create(scriptState);
   ScriptPromise promise = resolver->promise();
   ExecutionContext* executionContext = scriptState->getExecutionContext();
+  DCHECK(executionContext->isSecureContext());  // [SecureContext] in IDL
   SecurityOrigin* securityOrigin = executionContext->getSecurityOrigin();
   if (securityOrigin->isUnique()) {
-    resolver->reject(DOMException::create(NotSupportedError));
-    return promise;
-  }
-  // IDL has: [SecureContext]
-  String errorMessage;
-  if (!executionContext->isSecureContext(errorMessage)) {
-    resolver->reject(DOMException::create(SecurityError, errorMessage));
+    resolver->reject(V8ThrowException::createTypeError(
+        scriptState->isolate(), uniqueOriginErrorMessage));
     return promise;
   }
 
diff --git a/third_party/WebKit/Source/modules/quota/StorageManager.idl b/third_party/WebKit/Source/modules/quota/StorageManager.idl
index fc4674a..086c45c 100644
--- a/third_party/WebKit/Source/modules/quota/StorageManager.idl
+++ b/third_party/WebKit/Source/modules/quota/StorageManager.idl
@@ -4,6 +4,7 @@
 
 // https://storage.spec.whatwg.org/#storagemanager
 
+// TODO(jsbell): Should have [SecureContext] on interface
 [
     Exposed=(Window,Worker),
     RuntimeEnabled=DurableStorage,
diff --git a/third_party/WebKit/Source/modules/quota/WorkerNavigatorStorageQuota.idl b/third_party/WebKit/Source/modules/quota/WorkerNavigatorStorageQuota.idl
index 04c09ce..35a737d 100644
--- a/third_party/WebKit/Source/modules/quota/WorkerNavigatorStorageQuota.idl
+++ b/third_party/WebKit/Source/modules/quota/WorkerNavigatorStorageQuota.idl
@@ -19,5 +19,5 @@
 
 partial interface WorkerNavigator {
     // https://storage.spec.whatwg.org/#api
-    [RuntimeEnabled=DurableStorage] readonly attribute StorageManager storage;
+    [SecureContext, RuntimeEnabled=DurableStorage] readonly attribute StorageManager storage;
 };
diff --git a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
index cc5f759..ccc85c2b 100644
--- a/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
+++ b/third_party/WebKit/Source/modules/webgl/WebGLRenderingContextBase.cpp
@@ -660,9 +660,8 @@
   }
   if (contextProvider && !contextProvider->bindToCurrentThread()) {
     contextProvider = nullptr;
-    String errorString(glInfo.errorMessage.utf8().data());
-    errorString.insert("bindToCurrentThread failed: ", 0);
-    glInfo.errorMessage = errorString;
+    glInfo.errorMessage =
+        String("bindToCurrentThread failed: " + String(glInfo.errorMessage));
   }
   if (!contextProvider || shouldFailContextCreationForTesting) {
     shouldFailContextCreationForTesting = false;
diff --git a/third_party/WebKit/Source/platform/FrameViewBase.cpp b/third_party/WebKit/Source/platform/FrameViewBase.cpp
index 538f3c3..b48054ff 100644
--- a/third_party/WebKit/Source/platform/FrameViewBase.cpp
+++ b/third_party/WebKit/Source/platform/FrameViewBase.cpp
@@ -57,9 +57,11 @@
   return 0;
 }
 
-IntRect FrameViewBase::convertFromRootFrame(const IntRect& rectInRootFrame) const {
+IntRect FrameViewBase::convertFromRootFrame(
+    const IntRect& rectInRootFrame) const {
   if (const FrameViewBase* parentFrameViewBase = parent()) {
-    IntRect parentRect = parentFrameViewBase->convertFromRootFrame(rectInRootFrame);
+    IntRect parentRect =
+        parentFrameViewBase->convertFromRootFrame(rectInRootFrame);
     return convertFromContainingWidget(parentRect);
   }
   return rectInRootFrame;
@@ -73,9 +75,11 @@
   return localRect;
 }
 
-IntPoint FrameViewBase::convertFromRootFrame(const IntPoint& pointInRootFrame) const {
+IntPoint FrameViewBase::convertFromRootFrame(
+    const IntPoint& pointInRootFrame) const {
   if (const FrameViewBase* parentFrameViewBase = parent()) {
-    IntPoint parentPoint = parentFrameViewBase->convertFromRootFrame(pointInRootFrame);
+    IntPoint parentPoint =
+        parentFrameViewBase->convertFromRootFrame(pointInRootFrame);
     return convertFromContainingWidget(parentPoint);
   }
   return pointInRootFrame;
@@ -83,8 +87,8 @@
 
 FloatPoint FrameViewBase::convertFromRootFrame(
     const FloatPoint& pointInRootFrame) const {
-  // FrameViewBase / windows are required to be IntPoint aligned, but we may need to
-  // convert FloatPoint values within them (eg. for event co-ordinates).
+  // FrameViewBase / windows are required to be IntPoint aligned, but we may
+  // need to convert FloatPoint values within them (eg. for event co-ordinates).
   IntPoint flooredPoint = flooredIntPoint(pointInRootFrame);
   FloatPoint parentPoint = this->convertFromRootFrame(flooredPoint);
   FloatSize windowFraction = pointInRootFrame - flooredPoint;
@@ -110,7 +114,8 @@
   return localPoint;
 }
 
-IntRect FrameViewBase::convertToContainingWidget(const IntRect& localRect) const {
+IntRect FrameViewBase::convertToContainingWidget(
+    const IntRect& localRect) const {
   if (const FrameViewBase* parentFrameViewBase = parent()) {
     IntRect parentRect(localRect);
     parentRect.setLocation(
@@ -120,7 +125,8 @@
   return localRect;
 }
 
-IntRect FrameViewBase::convertFromContainingWidget(const IntRect& parentRect) const {
+IntRect FrameViewBase::convertFromContainingWidget(
+    const IntRect& parentRect) const {
   if (const FrameViewBase* parentFrameViewBase = parent()) {
     IntRect localRect = parentRect;
     localRect.setLocation(
@@ -131,7 +137,8 @@
   return parentRect;
 }
 
-IntPoint FrameViewBase::convertToContainingWidget(const IntPoint& localPoint) const {
+IntPoint FrameViewBase::convertToContainingWidget(
+    const IntPoint& localPoint) const {
   if (const FrameViewBase* parentFrameViewBase = parent())
     return parentFrameViewBase->convertChildToSelf(this, localPoint);
 
@@ -147,12 +154,12 @@
 }
 
 IntPoint FrameViewBase::convertChildToSelf(const FrameViewBase*,
-                                    const IntPoint& point) const {
+                                           const IntPoint& point) const {
   return point;
 }
 
 IntPoint FrameViewBase::convertSelfToChild(const FrameViewBase*,
-                                    const IntPoint& point) const {
+                                           const IntPoint& point) const {
   return point;
 }
 
diff --git a/third_party/WebKit/Source/platform/FrameViewBase.h b/third_party/WebKit/Source/platform/FrameViewBase.h
index 7f052e1..6692b28 100644
--- a/third_party/WebKit/Source/platform/FrameViewBase.h
+++ b/third_party/WebKit/Source/platform/FrameViewBase.h
@@ -44,10 +44,11 @@
 // The FrameViewBase class serves as a base class for FrameView, Scrollbar, and
 // PluginView.
 //
-// FrameViewBases are connected in a hierarchy, with the restriction that plugins and
-// scrollbars are always leaves of the tree. Only FrameView can have children
-// (and therefore the FrameViewBase class has no concept of children).
-class PLATFORM_EXPORT FrameViewBase : public GarbageCollectedFinalized<FrameViewBase> {
+// FrameViewBases are connected in a hierarchy, with the restriction that
+// plugins and scrollbars are always leaves of the tree. Only FrameView can have
+// children (and therefore the FrameViewBase class has no concept of children).
+class PLATFORM_EXPORT FrameViewBase
+    : public GarbageCollectedFinalized<FrameViewBase> {
  public:
   FrameViewBase();
   virtual ~FrameViewBase();
@@ -94,7 +95,7 @@
   virtual bool isPluginContainer() const { return false; }
   virtual bool isScrollbar() const { return false; }
 
-  virtual void setParent(FrameViewBase *);
+  virtual void setParent(FrameViewBase*);
   FrameViewBase* parent() const { return m_parent; }
   FrameViewBase* root() const;
 
@@ -117,8 +118,10 @@
   virtual IntPoint convertFromContainingWidget(const IntPoint&) const;
 
   // Virtual methods to convert points to/from child frameviewbases.
-  virtual IntPoint convertChildToSelf(const FrameViewBase *, const IntPoint&) const;
-  virtual IntPoint convertSelfToChild(const FrameViewBase *, const IntPoint&) const;
+  virtual IntPoint convertChildToSelf(const FrameViewBase*,
+                                      const IntPoint&) const;
+  virtual IntPoint convertSelfToChild(const FrameViewBase*,
+                                      const IntPoint&) const;
 
   // Notifies this frameviewbase that it will no longer be receiving events.
   virtual void eventListenersRemoved() {}
diff --git a/third_party/WebKit/Source/platform/HostWindow.h b/third_party/WebKit/Source/platform/HostWindow.h
index 056e4f0..c65486f2 100644
--- a/third_party/WebKit/Source/platform/HostWindow.h
+++ b/third_party/WebKit/Source/platform/HostWindow.h
@@ -48,7 +48,8 @@
   virtual void invalidateRect(const IntRect& updateRect) = 0;
 
   // Converts the rect from the viewport coordinates to screen coordinates.
-  virtual IntRect viewportToScreen(const IntRect&, const FrameViewBase*) const = 0;
+  virtual IntRect viewportToScreen(const IntRect&,
+                                   const FrameViewBase*) const = 0;
 
   // Converts the scalar value from the window coordinates to the viewport
   // scale.
diff --git a/third_party/WebKit/Source/platform/exported/WebScrollbarThemeClientImpl.cpp b/third_party/WebKit/Source/platform/exported/WebScrollbarThemeClientImpl.cpp
index 4e85032..a8f597ce 100644
--- a/third_party/WebKit/Source/platform/exported/WebScrollbarThemeClientImpl.cpp
+++ b/third_party/WebKit/Source/platform/exported/WebScrollbarThemeClientImpl.cpp
@@ -63,13 +63,13 @@
   return m_scrollbar.location();
 }
 
-Widget* WebScrollbarThemeClientImpl::parent() const {
+FrameViewBase* WebScrollbarThemeClientImpl::parent() const {
   // Unused by Chromium scrollbar themes.
   ASSERT_NOT_REACHED();
   return 0;
 }
 
-Widget* WebScrollbarThemeClientImpl::root() const {
+FrameViewBase* WebScrollbarThemeClientImpl::root() const {
   // Unused by Chromium scrollbar themes.
   ASSERT_NOT_REACHED();
   return 0;
diff --git a/third_party/WebKit/Source/platform/heap/HeapPage.h b/third_party/WebKit/Source/platform/heap/HeapPage.h
index cc59192..5a9a56c 100644
--- a/third_party/WebKit/Source/platform/heap/HeapPage.h
+++ b/third_party/WebKit/Source/platform/heap/HeapPage.h
@@ -873,16 +873,32 @@
 }
 
 #if CPU(64BIT)
+ALWAYS_INLINE uint32_t RotateLeft16(uint32_t x) {
+#if COMPILER(MSVC)
+  return _lrotr(x, 16);
+#else
+  // http://blog.regehr.org/archives/1063
+  return (x << 16) | (x >> (-16 & 31));
+#endif
+}
+
 inline uint32_t HeapObjectHeader::getMagic() const {
-  const uintptr_t random1 =
-      ~(reinterpret_cast<uintptr_t>(
-            base::trace_event::MemoryAllocatorDump::kNameSize) >>
-        16);
+// Ignore C4319: It is OK to 0-extend into the high-order bits of the uintptr_t
+// on 64-bit, in this case.
+#if COMPILER(MSVC)
+#pragma warning(push)
+#pragma warning(disable : 4319)
+#endif
+
+  const uintptr_t random1 = ~(RotateLeft16(reinterpret_cast<uintptr_t>(
+      base::trace_event::MemoryAllocatorDump::kNameSize)));
 
 #if OS(WIN)
-  const uintptr_t random2 = ~(reinterpret_cast<uintptr_t>(::ReadFile) << 16);
+  const uintptr_t random2 =
+      ~(RotateLeft16(reinterpret_cast<uintptr_t>(::ReadFile)));
 #elif OS(POSIX)
-  const uintptr_t random2 = ~(reinterpret_cast<uintptr_t>(::read) << 16);
+  const uintptr_t random2 =
+      ~(RotateLeft16(reinterpret_cast<uintptr_t>(::read)));
 #else
 #error OS not supported
 #endif
@@ -902,9 +918,13 @@
 #error architecture not supported
 #endif
 
+#if COMPILER(MSVC)
+#pragma warning(pop)
+#endif
+
   return random;
 }
-#endif
+#endif  // CPU(64BIT)
 
 NO_SANITIZE_ADDRESS inline bool HeapObjectHeader::isWrapperHeaderMarked()
     const {
diff --git a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
index 266e804..3522582 100644
--- a/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
+++ b/third_party/WebKit/Source/platform/scroll/ScrollableArea.h
@@ -181,28 +181,28 @@
   void setScrollCornerNeedsPaintInvalidation();
   virtual void getTickmarks(Vector<IntRect>&) const {}
 
-  // Convert points and rects between the scrollbar and its containing Widget.
-  // The client needs to implement these in order to be aware of layout effects
-  // like CSS transforms.
+  // Convert points and rects between the scrollbar and its containing
+  // FrameViewBase. The client needs to implement these in order to be aware of
+  // layout effects like CSS transforms.
   virtual IntRect convertFromScrollbarToContainingWidget(
       const Scrollbar& scrollbar,
       const IntRect& scrollbarRect) const {
-    return scrollbar.Widget::convertToContainingWidget(scrollbarRect);
+    return scrollbar.FrameViewBase::convertToContainingWidget(scrollbarRect);
   }
   virtual IntRect convertFromContainingWidgetToScrollbar(
       const Scrollbar& scrollbar,
       const IntRect& parentRect) const {
-    return scrollbar.Widget::convertFromContainingWidget(parentRect);
+    return scrollbar.FrameViewBase::convertFromContainingWidget(parentRect);
   }
   virtual IntPoint convertFromScrollbarToContainingWidget(
       const Scrollbar& scrollbar,
       const IntPoint& scrollbarPoint) const {
-    return scrollbar.Widget::convertToContainingWidget(scrollbarPoint);
+    return scrollbar.FrameViewBase::convertToContainingWidget(scrollbarPoint);
   }
   virtual IntPoint convertFromContainingWidgetToScrollbar(
       const Scrollbar& scrollbar,
       const IntPoint& parentPoint) const {
-    return scrollbar.Widget::convertFromContainingWidget(parentPoint);
+    return scrollbar.FrameViewBase::convertFromContainingWidget(parentPoint);
   }
 
   virtual Scrollbar* horizontalScrollbar() const { return nullptr; }
@@ -336,7 +336,7 @@
       OverlayScrollbarClipBehavior = IgnoreOverlayScrollbarSize) const;
 
   // Returns the widget associated with this ScrollableArea.
-  virtual Widget* getWidget() { return nullptr; }
+  virtual FrameViewBase* getWidget() { return nullptr; }
 
   virtual LayoutBox* layoutBox() const { return nullptr; }
 
diff --git a/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp b/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp
index e4bf898e7..1783e6c8 100644
--- a/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp
+++ b/third_party/WebKit/Source/platform/scroll/Scrollbar.cpp
@@ -74,7 +74,7 @@
   m_themeScrollbarThickness = thickness;
   if (m_hostWindow)
     thickness = m_hostWindow->windowToViewportScalar(thickness);
-  Widget::setFrameRect(IntRect(0, 0, thickness, thickness));
+  FrameViewBase::setFrameRect(IntRect(0, 0, thickness, thickness));
 
   m_currentPos = scrollableAreaCurrentPos();
 }
@@ -86,14 +86,14 @@
 DEFINE_TRACE(Scrollbar) {
   visitor->trace(m_scrollableArea);
   visitor->trace(m_hostWindow);
-  Widget::trace(visitor);
+  FrameViewBase::trace(visitor);
 }
 
 void Scrollbar::setFrameRect(const IntRect& frameRect) {
   if (frameRect == this->frameRect())
     return;
 
-  Widget::setFrameRect(frameRect);
+  FrameViewBase::setFrameRect(frameRect);
   setNeedsPaintInvalidation(AllParts);
 }
 
@@ -157,7 +157,7 @@
     return;
 
   if (!theme().paint(*this, context, cullRect))
-    Widget::paint(context, cullRect);
+    FrameViewBase::paint(context, cullRect);
 }
 
 void Scrollbar::autoscrollTimerFired(TimerBase*) {
@@ -573,7 +573,7 @@
     return m_scrollableArea->convertFromScrollbarToContainingWidget(*this,
                                                                     localRect);
 
-  return Widget::convertToContainingWidget(localRect);
+  return FrameViewBase::convertToContainingWidget(localRect);
 }
 
 IntRect Scrollbar::convertFromContainingWidget(
@@ -582,7 +582,7 @@
     return m_scrollableArea->convertFromContainingWidgetToScrollbar(*this,
                                                                     parentRect);
 
-  return Widget::convertFromContainingWidget(parentRect);
+  return FrameViewBase::convertFromContainingWidget(parentRect);
 }
 
 IntPoint Scrollbar::convertToContainingWidget(
@@ -591,7 +591,7 @@
     return m_scrollableArea->convertFromScrollbarToContainingWidget(*this,
                                                                     localPoint);
 
-  return Widget::convertToContainingWidget(localPoint);
+  return FrameViewBase::convertToContainingWidget(localPoint);
 }
 
 IntPoint Scrollbar::convertFromContainingWidget(
@@ -600,7 +600,7 @@
     return m_scrollableArea->convertFromContainingWidgetToScrollbar(
         *this, parentPoint);
 
-  return Widget::convertFromContainingWidget(parentPoint);
+  return FrameViewBase::convertFromContainingWidget(parentPoint);
 }
 
 float Scrollbar::scrollableAreaCurrentPos() const {
diff --git a/third_party/WebKit/Source/platform/scroll/Scrollbar.h b/third_party/WebKit/Source/platform/scroll/Scrollbar.h
index 6549ff2..8a1f8d6 100644
--- a/third_party/WebKit/Source/platform/scroll/Scrollbar.h
+++ b/third_party/WebKit/Source/platform/scroll/Scrollbar.h
@@ -26,8 +26,8 @@
 #ifndef Scrollbar_h
 #define Scrollbar_h
 
+#include "platform/FrameViewBase.h"
 #include "platform/Timer.h"
-#include "platform/Widget.h"
 #include "platform/graphics/paint/DisplayItem.h"
 #include "platform/heap/Handle.h"
 #include "platform/scroll/ScrollTypes.h"
@@ -44,7 +44,7 @@
 class WebGestureEvent;
 class WebMouseEvent;
 
-class PLATFORM_EXPORT Scrollbar : public Widget,
+class PLATFORM_EXPORT Scrollbar : public FrameViewBase,
                                   public ScrollbarThemeClient,
                                   public DisplayItemClient {
  public:
@@ -67,18 +67,18 @@
   ~Scrollbar() override;
 
   // ScrollbarThemeClient implementation.
-  int x() const override { return Widget::x(); }
-  int y() const override { return Widget::y(); }
-  int width() const override { return Widget::width(); }
-  int height() const override { return Widget::height(); }
-  IntSize size() const override { return Widget::size(); }
-  IntPoint location() const override { return Widget::location(); }
+  int x() const override { return FrameViewBase::x(); }
+  int y() const override { return FrameViewBase::y(); }
+  int width() const override { return FrameViewBase::width(); }
+  int height() const override { return FrameViewBase::height(); }
+  IntSize size() const override { return FrameViewBase::size(); }
+  IntPoint location() const override { return FrameViewBase::location(); }
 
-  Widget* parent() const override { return Widget::parent(); }
-  Widget* root() const override { return Widget::root(); }
+  FrameViewBase* parent() const override { return FrameViewBase::parent(); }
+  FrameViewBase* root() const override { return FrameViewBase::root(); }
 
   void setFrameRect(const IntRect&) override;
-  IntRect frameRect() const override { return Widget::frameRect(); }
+  IntRect frameRect() const override { return FrameViewBase::frameRect(); }
 
   ScrollbarOverlayColorTheme getScrollbarOverlayColorTheme() const override;
   void getTickmarks(Vector<IntRect>&) const override;
@@ -86,7 +86,7 @@
 
   IntPoint convertFromRootFrame(
       const IntPoint& pointInRootFrame) const override {
-    return Widget::convertFromRootFrame(pointInRootFrame);
+    return FrameViewBase::convertFromRootFrame(pointInRootFrame);
   }
 
   bool isCustomScrollbar() const override { return false; }
@@ -261,10 +261,10 @@
 };
 
 DEFINE_TYPE_CASTS(Scrollbar,
-                  Widget,
-                  widget,
-                  widget->isScrollbar(),
-                  widget.isScrollbar());
+                  FrameViewBase,
+                  frameViewBase,
+                  frameViewBase->isScrollbar(),
+                  frameViewBase.isScrollbar());
 
 }  // namespace blink
 
diff --git a/third_party/WebKit/Source/wtf/text/AtomicString.cpp b/third_party/WebKit/Source/wtf/text/AtomicString.cpp
index 74acc81..e91194b3 100644
--- a/third_party/WebKit/Source/wtf/text/AtomicString.cpp
+++ b/third_party/WebKit/Source/wtf/text/AtomicString.cpp
@@ -87,6 +87,13 @@
   return AtomicString(newImpl.release());
 }
 
+AtomicString AtomicString::upperASCII() const {
+  StringImpl* impl = this->impl();
+  if (UNLIKELY(!impl))
+    return *this;
+  return AtomicString(impl->upperASCII());
+}
+
 template <typename IntegerType>
 static AtomicString integerToAtomicString(IntegerType input) {
   IntegerToStringConverter<IntegerType> converter(input);
diff --git a/third_party/WebKit/Source/wtf/text/AtomicString.h b/third_party/WebKit/Source/wtf/text/AtomicString.h
index 4f4a96b..f89af9c7 100644
--- a/third_party/WebKit/Source/wtf/text/AtomicString.h
+++ b/third_party/WebKit/Source/wtf/text/AtomicString.h
@@ -161,16 +161,16 @@
   }
   bool endsWith(UChar character) const { return m_string.endsWith(character); }
 
-  // Returns a lowercase/uppercase version of the string. These functions might
-  // convert non-ASCII characters to ASCII characters. For example, lower() for
-  // U+212A is 'k', upper() for U+017F is 'S'.
-  // These functions are rarely used to implement web platform features.
+  // Returns a lowercase version of the string. This function might
+  // convert non-ASCII characters to ASCII characters. For example,
+  // lower() for U+212A is 'k'.
+  // This function is rarely used to implement web platform features.
   AtomicString lower() const;
-  AtomicString upper() const { return AtomicString(impl()->upper()); }
 
-  // Returns a lowercase version of the string. This function converts only
-  // upper-case ASCII characters.
+  // Returns a lowercase/uppercase version of the string.
+  // These functions convert ASCII characters only.
   AtomicString lowerASCII() const;
+  AtomicString upperASCII() const;
 
   int toInt(bool* ok = 0) const { return m_string.toInt(ok); }
   double toDouble(bool* ok = 0) const { return m_string.toDouble(ok); }
diff --git a/third_party/WebKit/Source/wtf/text/StringImpl.cpp b/third_party/WebKit/Source/wtf/text/StringImpl.cpp
index 38252ebc..684b01b 100644
--- a/third_party/WebKit/Source/wtf/text/StringImpl.cpp
+++ b/third_party/WebKit/Source/wtf/text/StringImpl.cpp
@@ -803,6 +803,28 @@
   return newImpl.release();
 }
 
+PassRefPtr<StringImpl> StringImpl::upperASCII() {
+  if (is8Bit()) {
+    LChar* data8;
+    RefPtr<StringImpl> newImpl = createUninitialized(m_length, data8);
+
+    for (unsigned i = 0; i < m_length; ++i) {
+      LChar c = characters8()[i];
+      data8[i] = isASCIILower(c) ? toASCIIUpper(c) : c;
+    }
+    return newImpl.release();
+  }
+
+  UChar* data16;
+  RefPtr<StringImpl> newImpl = createUninitialized(m_length, data16);
+
+  for (unsigned i = 0; i < m_length; ++i) {
+    UChar c = characters16()[i];
+    data16[i] = isASCIILower(c) ? toASCIIUpper(c) : c;
+  }
+  return newImpl.release();
+}
+
 static inline bool localeIdMatchesLang(const AtomicString& localeId,
                                        const StringView& lang) {
   RELEASE_ASSERT(lang.length() >= 2 && lang.length() <= 3);
diff --git a/third_party/WebKit/Source/wtf/text/StringImpl.h b/third_party/WebKit/Source/wtf/text/StringImpl.h
index afdb6af..97f2c67 100644
--- a/third_party/WebKit/Source/wtf/text/StringImpl.h
+++ b/third_party/WebKit/Source/wtf/text/StringImpl.h
@@ -381,6 +381,7 @@
   PassRefPtr<StringImpl> lower();
   PassRefPtr<StringImpl> lowerASCII();
   PassRefPtr<StringImpl> upper();
+  PassRefPtr<StringImpl> upperASCII();
   PassRefPtr<StringImpl> lower(const AtomicString& localeIdentifier);
   PassRefPtr<StringImpl> upper(const AtomicString& localeIdentifier);
 
diff --git a/third_party/WebKit/Source/wtf/text/StringImplTest.cpp b/third_party/WebKit/Source/wtf/text/StringImplTest.cpp
index 9843a07..8e8835a 100644
--- a/third_party/WebKit/Source/wtf/text/StringImplTest.cpp
+++ b/third_party/WebKit/Source/wtf/text/StringImplTest.cpp
@@ -100,4 +100,61 @@
       StringImpl::create(testWithNonASCIIComparison, 2)->lowerASCII().get()));
 }
 
+TEST(StringImplTest, UpperASCII) {
+  RefPtr<StringImpl> testStringImpl = StringImpl::create("LINK");
+  EXPECT_TRUE(testStringImpl->is8Bit());
+  EXPECT_TRUE(StringImpl::create("a\xE1")->is8Bit());
+
+  EXPECT_TRUE(equal(testStringImpl.get(),
+                    StringImpl::create("link")->upperASCII().get()));
+  EXPECT_TRUE(equal(testStringImpl.get(),
+                    StringImpl::create("LINK")->upperASCII().get()));
+  EXPECT_TRUE(equal(testStringImpl.get(),
+                    StringImpl::create("lInk")->upperASCII().get()));
+
+  EXPECT_TRUE(equal(StringImpl::create("LINK")->upper().get(),
+                    StringImpl::create("LINK")->upperASCII().get()));
+  EXPECT_TRUE(equal(StringImpl::create("lInk")->upper().get(),
+                    StringImpl::create("lInk")->upperASCII().get()));
+
+  EXPECT_TRUE(equal(StringImpl::create("A\xE1").get(),
+                    StringImpl::create("a\xE1")->upperASCII().get()));
+  EXPECT_TRUE(equal(StringImpl::create("A\xC1").get(),
+                    StringImpl::create("a\xC1")->upperASCII().get()));
+
+  EXPECT_FALSE(equal(StringImpl::create("A\xE1").get(),
+                     StringImpl::create("a\xC1")->upperASCII().get()));
+  EXPECT_FALSE(equal(StringImpl::create("A\xE1").get(),
+                     StringImpl::create("A\xC1")->upperASCII().get()));
+
+  static const UChar test[5] = {0x006c, 0x0069, 0x006e, 0x006b, 0};  // link
+  static const UChar testCapitalized[5] = {0x004c, 0x0049, 0x004e, 0x004b,
+                                           0};  // LINK
+
+  RefPtr<StringImpl> testStringImpl16 = StringImpl::create(testCapitalized, 4);
+  EXPECT_FALSE(testStringImpl16->is8Bit());
+
+  EXPECT_TRUE(equal(testStringImpl16.get(),
+                    StringImpl::create(test, 4)->upperASCII().get()));
+  EXPECT_TRUE(
+      equal(testStringImpl16.get(),
+            StringImpl::create(testCapitalized, 4)->upperASCII().get()));
+
+  static const UChar testWithNonASCII[3] = {0x0061, 0x00e1, 0};  // a\xE1
+  static const UChar testWithNonASCIIComparison[3] = {0x0061, 0x00c1,
+                                                      0};  // a\xC1
+  static const UChar testWithNonASCIICapitalized[3] = {0x0041, 0x00e1,
+                                                       0};  // A\xE1
+
+  // Make sure we support RefPtr<const StringImpl>.
+  RefPtr<const StringImpl> constRef = testStringImpl->isolatedCopy();
+  DCHECK(constRef->hasOneRef());
+  EXPECT_TRUE(
+      equal(StringImpl::create(testWithNonASCIICapitalized, 2).get(),
+            StringImpl::create(testWithNonASCII, 2)->upperASCII().get()));
+  EXPECT_FALSE(equal(
+      StringImpl::create(testWithNonASCIICapitalized, 2).get(),
+      StringImpl::create(testWithNonASCIIComparison, 2)->upperASCII().get()));
+}
+
 }  // namespace WTF
diff --git a/third_party/WebKit/Source/wtf/text/WTFString.cpp b/third_party/WebKit/Source/wtf/text/WTFString.cpp
index b547cbd..f59f40b 100644
--- a/third_party/WebKit/Source/wtf/text/WTFString.cpp
+++ b/third_party/WebKit/Source/wtf/text/WTFString.cpp
@@ -294,6 +294,12 @@
   return m_impl->upper(localeIdentifier);
 }
 
+String String::upperASCII() const {
+  if (!m_impl)
+    return String();
+  return m_impl->upperASCII();
+}
+
 String String::stripWhiteSpace() const {
   if (!m_impl)
     return String();
diff --git a/third_party/WebKit/Source/wtf/text/WTFString.h b/third_party/WebKit/Source/wtf/text/WTFString.h
index 9ba534a6..dd517e4a 100644
--- a/third_party/WebKit/Source/wtf/text/WTFString.h
+++ b/third_party/WebKit/Source/wtf/text/WTFString.h
@@ -293,6 +293,10 @@
   String lower(const AtomicString& localeIdentifier) const;
   String upper(const AtomicString& localeIdentifier) const;
 
+  // Returns a uppercase version of the string.
+  // This function converts ASCII characters only.
+  String upperASCII() const;
+
   String stripWhiteSpace() const;
   String stripWhiteSpace(IsWhiteSpaceFunctionPtr) const;
   String simplifyWhiteSpace(StripBehavior = StripExtraWhiteSpace) const;
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/cpp.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/cpp.py
index eccd0e51..e4b3ead6 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/cpp.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/cpp.py
@@ -2091,7 +2091,7 @@
     for operator in ['==', '!=', '>=', '>', '<=', '<']:
         if replaceable_check(operator, current_macro, line):
             error(line_number, 'readability/check', 2,
-                  'Consider using %s instead of %s(a %s b)' % (
+                  'Consider using %s(a, b) instead of %s(a %s b)' % (
                       _CHECK_REPLACEMENT[current_macro][operator],
                       current_macro, operator))
             break
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py
index 810bfbe2..11bc5283 100644
--- a/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/style/checkers/cpp_unittest.py
@@ -1455,91 +1455,91 @@
     # CHECK/EXPECT_TRUE/EXPECT_FALSE replacements
     def test_check_check(self):
         self.assert_lint('CHECK(x == 42)',
-                         'Consider using CHECK_EQ instead of CHECK(a == b)'
+                         'Consider using CHECK_EQ(a, b) instead of CHECK(a == b)'
                          '  [readability/check] [2]')
         self.assert_lint('CHECK(x != 42)',
-                         'Consider using CHECK_NE instead of CHECK(a != b)'
+                         'Consider using CHECK_NE(a, b) instead of CHECK(a != b)'
                          '  [readability/check] [2]')
         self.assert_lint('CHECK(x >= 42)',
-                         'Consider using CHECK_GE instead of CHECK(a >= b)'
+                         'Consider using CHECK_GE(a, b) instead of CHECK(a >= b)'
                          '  [readability/check] [2]')
         self.assert_lint('CHECK(x > 42)',
-                         'Consider using CHECK_GT instead of CHECK(a > b)'
+                         'Consider using CHECK_GT(a, b) instead of CHECK(a > b)'
                          '  [readability/check] [2]')
         self.assert_lint('CHECK(x <= 42)',
-                         'Consider using CHECK_LE instead of CHECK(a <= b)'
+                         'Consider using CHECK_LE(a, b) instead of CHECK(a <= b)'
                          '  [readability/check] [2]')
         self.assert_lint('CHECK(x < 42)',
-                         'Consider using CHECK_LT instead of CHECK(a < b)'
+                         'Consider using CHECK_LT(a, b) instead of CHECK(a < b)'
                          '  [readability/check] [2]')
 
         self.assert_lint('DCHECK(x == 42)',
-                         'Consider using DCHECK_EQ instead of DCHECK(a == b)'
+                         'Consider using DCHECK_EQ(a, b) instead of DCHECK(a == b)'
                          '  [readability/check] [2]')
         self.assert_lint('DCHECK(x != 42)',
-                         'Consider using DCHECK_NE instead of DCHECK(a != b)'
+                         'Consider using DCHECK_NE(a, b) instead of DCHECK(a != b)'
                          '  [readability/check] [2]')
         self.assert_lint('DCHECK(x >= 42)',
-                         'Consider using DCHECK_GE instead of DCHECK(a >= b)'
+                         'Consider using DCHECK_GE(a, b) instead of DCHECK(a >= b)'
                          '  [readability/check] [2]')
         self.assert_lint('DCHECK(x > 42)',
-                         'Consider using DCHECK_GT instead of DCHECK(a > b)'
+                         'Consider using DCHECK_GT(a, b) instead of DCHECK(a > b)'
                          '  [readability/check] [2]')
         self.assert_lint('DCHECK(x <= 42)',
-                         'Consider using DCHECK_LE instead of DCHECK(a <= b)'
+                         'Consider using DCHECK_LE(a, b) instead of DCHECK(a <= b)'
                          '  [readability/check] [2]')
         self.assert_lint('DCHECK(x < 42)',
-                         'Consider using DCHECK_LT instead of DCHECK(a < b)'
+                         'Consider using DCHECK_LT(a, b) instead of DCHECK(a < b)'
                          '  [readability/check] [2]')
 
         self.assert_lint(
             'EXPECT_TRUE("42" == x)',
-            'Consider using EXPECT_EQ instead of EXPECT_TRUE(a == b)'
+            'Consider using EXPECT_EQ(a, b) instead of EXPECT_TRUE(a == b)'
             '  [readability/check] [2]')
         self.assert_lint(
             'EXPECT_TRUE("42" != x)',
-            'Consider using EXPECT_NE instead of EXPECT_TRUE(a != b)'
+            'Consider using EXPECT_NE(a, b) instead of EXPECT_TRUE(a != b)'
             '  [readability/check] [2]')
         self.assert_lint(
             'EXPECT_TRUE(+42 >= x)',
-            'Consider using EXPECT_GE instead of EXPECT_TRUE(a >= b)'
+            'Consider using EXPECT_GE(a, b) instead of EXPECT_TRUE(a >= b)'
             '  [readability/check] [2]')
         self.assert_lint(
             'EXPECT_TRUE_M(-42 > x)',
-            'Consider using EXPECT_GT_M instead of EXPECT_TRUE_M(a > b)'
+            'Consider using EXPECT_GT_M(a, b) instead of EXPECT_TRUE_M(a > b)'
             '  [readability/check] [2]')
         self.assert_lint(
             'EXPECT_TRUE_M(42U <= x)',
-            'Consider using EXPECT_LE_M instead of EXPECT_TRUE_M(a <= b)'
+            'Consider using EXPECT_LE_M(a, b) instead of EXPECT_TRUE_M(a <= b)'
             '  [readability/check] [2]')
         self.assert_lint(
             'EXPECT_TRUE_M(42L < x)',
-            'Consider using EXPECT_LT_M instead of EXPECT_TRUE_M(a < b)'
+            'Consider using EXPECT_LT_M(a, b) instead of EXPECT_TRUE_M(a < b)'
             '  [readability/check] [2]')
 
         self.assert_lint(
             'EXPECT_FALSE(x == 42)',
-            'Consider using EXPECT_NE instead of EXPECT_FALSE(a == b)'
+            'Consider using EXPECT_NE(a, b) instead of EXPECT_FALSE(a == b)'
             '  [readability/check] [2]')
         self.assert_lint(
             'EXPECT_FALSE(x != 42)',
-            'Consider using EXPECT_EQ instead of EXPECT_FALSE(a != b)'
+            'Consider using EXPECT_EQ(a, b) instead of EXPECT_FALSE(a != b)'
             '  [readability/check] [2]')
         self.assert_lint(
             'EXPECT_FALSE(x >= 42)',
-            'Consider using EXPECT_LT instead of EXPECT_FALSE(a >= b)'
+            'Consider using EXPECT_LT(a, b) instead of EXPECT_FALSE(a >= b)'
             '  [readability/check] [2]')
         self.assert_lint(
             'ASSERT_FALSE(x > 42)',
-            'Consider using ASSERT_LE instead of ASSERT_FALSE(a > b)'
+            'Consider using ASSERT_LE(a, b) instead of ASSERT_FALSE(a > b)'
             '  [readability/check] [2]')
         self.assert_lint(
             'ASSERT_FALSE(x <= 42)',
-            'Consider using ASSERT_GT instead of ASSERT_FALSE(a <= b)'
+            'Consider using ASSERT_GT(a, b) instead of ASSERT_FALSE(a <= b)'
             '  [readability/check] [2]')
         self.assert_lint(
             'ASSERT_FALSE_M(x < 42)',
-            'Consider using ASSERT_GE_M instead of ASSERT_FALSE_M(a < b)'
+            'Consider using ASSERT_GE_M(a, b) instead of ASSERT_FALSE_M(a < b)'
             '  [readability/check] [2]')
 
         self.assert_lint('CHECK(some_iterator == obj.end())', '')
@@ -1550,23 +1550,23 @@
         self.assert_lint('CHECK(CreateTestFile(dir, (1 >> 20)));', '')
 
         self.assert_lint('CHECK(x<42)',
-                         'Consider using CHECK_LT instead of CHECK(a < b)'
+                         'Consider using CHECK_LT(a, b) instead of CHECK(a < b)'
                          '  [readability/check] [2]')
         self.assert_lint('CHECK(x>42)',
-                         'Consider using CHECK_GT instead of CHECK(a > b)'
+                         'Consider using CHECK_GT(a, b) instead of CHECK(a > b)'
                          '  [readability/check] [2]')
 
         self.assert_lint(
             '  EXPECT_TRUE(42 < x) // Random comment.',
-            'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
+            'Consider using EXPECT_LT(a, b) instead of EXPECT_TRUE(a < b)'
             '  [readability/check] [2]')
         self.assert_lint(
             'EXPECT_TRUE( 42 < x )',
-            'Consider using EXPECT_LT instead of EXPECT_TRUE(a < b)'
+            'Consider using EXPECT_LT(a, b) instead of EXPECT_TRUE(a < b)'
             '  [readability/check] [2]')
         self.assert_lint(
             'CHECK("foo" == "foo")',
-            'Consider using CHECK_EQ instead of CHECK(a == b)'
+            'Consider using CHECK_EQ(a, b) instead of CHECK(a == b)'
             '  [readability/check] [2]')
 
         self.assert_lint('CHECK_EQ("foo", "foo")', '')
diff --git a/third_party/freetype2/.clang-format b/third_party/freetype-android/.clang-format
similarity index 100%
rename from third_party/freetype2/.clang-format
rename to third_party/freetype-android/.clang-format
diff --git a/third_party/freetype-android/BUILD.gn b/third_party/freetype-android/BUILD.gn
index acca85a..c853c762 100644
--- a/third_party/freetype-android/BUILD.gn
+++ b/third_party/freetype-android/BUILD.gn
@@ -4,9 +4,6 @@
 
 import("//build/config/chromecast_build.gni")
 
-assert(is_android || is_chromecast,
-       "This library is only used on Android or Chromecast")
-
 config("freetype_config") {
   include_dirs = [
     "include",
@@ -14,10 +11,26 @@
   ]
 }
 
-source_set("freetype") {
+config("freetype-warnings") {
+  cflags = []
+
+  # The reduction of FreeType files to a minimum triggers -Wunused-function
+  # warnings in ftbase.c
+  cflags += [ "-Wno-unused-function" ]
+}
+
+config("freetype-visibility") {
+  cflags = []
+  cflags += [ "-fvisibility=default" ]
+}
+
+component("freetype") {
+  if (is_linux) {
+    output_name = "freetype"
+    output_extension = "so.6"
+  }
+
   sources = [
-    # The following files are not sorted alphabetically, but in the
-    # same order as in Android.mk to ease maintenance.
     "src/src/autofit/autofit.c",
     "src/src/base/ftbase.c",
     "src/src/base/ftbbox.c",
@@ -42,7 +55,8 @@
     "src/src/truetype/truetype.c",
   ]
 
-  if (is_chromecast) {
+  if (is_linux || is_chromecast) {
+    # Needed for content_shell on Linux and Chromecast, since fontconfig requires FT_Get_BDF_Property.
     sources += [ "src/src/base/ftbdf.c" ]
   }
 
@@ -57,7 +71,11 @@
 
   public_configs = [ ":freetype_config" ]
   configs -= [ "//build/config/compiler:chromium_code" ]
-  configs += [ "//build/config/compiler:no_chromium_code" ]
+  configs += [
+    "//build/config/compiler:no_chromium_code",
+    ":freetype-warnings",
+    ":freetype-visibility"
+  ]
 
   deps = [
     "//third_party/libpng",
diff --git a/third_party/freetype-android/OWNERS b/third_party/freetype-android/OWNERS
index a5ce419f..480c869 100644
--- a/third_party/freetype-android/OWNERS
+++ b/third_party/freetype-android/OWNERS
@@ -1,3 +1,4 @@
 wangxianzhu@chromium.org
 michaelbai@chromium.org
 bungeman@chromium.org
+drott@chromium.org
diff --git a/third_party/freetype-android/include/freetype-android-config/ftoption.h b/third_party/freetype-android/include/freetype-android-config/ftoption.h
index f419cc1..e2d22a87 100644
--- a/third_party/freetype-android/include/freetype-android-config/ftoption.h
+++ b/third_party/freetype-android/include/freetype-android-config/ftoption.h
@@ -366,7 +366,7 @@
   /*                                                                       */
   /*   Note that the `FOND' resource isn't checked.                        */
   /*                                                                       */
-#define FT_CONFIG_OPTION_MAC_FONTS
+/* #define FT_CONFIG_OPTION_MAC_FONTS */
 
 
   /*************************************************************************/
@@ -722,7 +722,7 @@
   /* Define TT_CONFIG_OPTION_BDF if you want to include support for        */
   /* an embedded `BDF ' table within SFNT-based bitmap formats.            */
   /*                                                                       */
-#define TT_CONFIG_OPTION_BDF
+/* #define TT_CONFIG_OPTION_BDF */
 
 
   /*************************************************************************/
diff --git a/third_party/freetype2/BUILD.gn b/third_party/freetype2/BUILD.gn
deleted file mode 100644
index 2627827..0000000
--- a/third_party/freetype2/BUILD.gn
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (c) 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.
-
-assert(is_linux, "This file should only be depended on from Linux.")
-
-config("freetype2_config") {
-  include_dirs = [
-    "include",
-    "src/include",
-  ]
-}
-
-shared_library("freetype2") {
-  output_name = "freetype"
-  output_extension = "so.6"
-
-  sources = [
-    "src/src/autofit/autofit.c",
-    "src/src/base/ftbase.c",
-    "src/src/base/ftbbox.c",
-    "src/src/base/ftbdf.c",
-    "src/src/base/ftbitmap.c",
-    "src/src/base/ftcid.c",
-    "src/src/base/ftdebug.c",
-    "src/src/base/ftfntfmt.c",
-    "src/src/base/ftfstype.c",
-    "src/src/base/ftgasp.c",
-    "src/src/base/ftglyph.c",
-    "src/src/base/ftgxval.c",
-    "src/src/base/ftinit.c",
-    "src/src/base/ftlcdfil.c",
-    "src/src/base/ftmm.c",
-    "src/src/base/ftstroke.c",
-    "src/src/base/ftsynth.c",
-    "src/src/base/ftsystem.c",
-    "src/src/base/fttype1.c",
-    "src/src/bdf/bdf.c",
-    "src/src/cff/cff.c",
-    "src/src/gzip/ftgzip.c",
-    "src/src/lzw/ftlzw.c",
-    "src/src/psaux/psaux.c",
-    "src/src/pshinter/pshinter.c",
-    "src/src/psnames/psnames.c",
-    "src/src/raster/raster.c",
-    "src/src/sfnt/sfnt.c",
-    "src/src/smooth/smooth.c",
-    "src/src/truetype/truetype.c",
-    "src/src/type1/type1.c",
-  ]
-
-  defines = [
-    "FT_CONFIG_OPTION_SYSTEM_ZLIB",
-
-    # TODO: Enable this option and figure out a way to address the cyclic
-    # dependency with HarfBuzz. crbug.com/617168
-    # "FT_CONFIG_OPTION_USE_HARFBUZZ",
-    "FT2_BUILD_LIBRARY",
-    "FT_CONFIG_CONFIG_H=<freetype-custom-config/ftconfig.h>",  # See comments in README.chromium.
-    "FT_CONFIG_MODULES_H=<freetype-custom-config/ftmodule.h>",  # See comments in README.chromium.
-    "FT_CONFIG_OPTION_H=<freetype-custom-config/ftoption.h>",  # See comments in README.chromium.
-  ]
-
-  configs -= [ "//build/config/compiler:chromium_code" ]
-  configs += [ "//build/config/compiler:no_chromium_code" ]
-  configs += [ ":freetype2_config" ]
-
-  public_configs = [ ":freetype2_config" ]
-
-  deps = [
-    "//build/config/sanitizers:deps",
-    "//third_party/libpng",
-    "//third_party/zlib",
-  ]
-}
diff --git a/third_party/freetype2/OWNERS b/third_party/freetype2/OWNERS
deleted file mode 100644
index f8ec284..0000000
--- a/third_party/freetype2/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-dpranke@chromium.org
diff --git a/third_party/freetype2/README.chromium b/third_party/freetype2/README.chromium
deleted file mode 100644
index 3815184..0000000
--- a/third_party/freetype2/README.chromium
+++ /dev/null
@@ -1,53 +0,0 @@
-Name: freetype2
-URL: git://git.sv.nongnu.org/freetype/freetype2.git
-Version: VER-2-7-1-updates
-Revision: e432ebf2e2c96e75f674af41f062d8b210de8491
-Security Critical: yes
-License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
-         JPEG Group) licenses"
-License File: src/docs/FTL.TXT
-License Android Compatible: yes
-
-Description:
-
-This version of Freetype is updated by checking out freetype from the above git
-URL, using the hash from "Revision:". Versions from 2.7.1 contain the level of
-OpenType font variations support that we require.
-
-The build files should approximate the output of
-
-make -Bn | rev | cut -d ' ' -f 1 | rev | grep "\.c$" | sort
-
-Currently the cache, patent checker (no longer used), bzip2 are excluded, as
-well as the following modules:
-t1cid_driver_class
-pfr_driver_class
-t42_driver_class
-winfnt_driver_class
-pcf_driver_class
-
-base/ftotval.c
-base/ftpfr.c
-base/ftwinfnt.c
-cid/type1cid.c
-pcf/pcf.c
-pfr/pfr.c
-type42/type42.c
-winfonts/winfnt.c
-
-Freetype depends on two header files to be supplied by the user to specify
-how to build the library, ftconfig.h and ftmodule.h (or equivalent filenames
-as defined by the FT_CONFIG_CONFIG_H and FT_CONFIG_MODULES_H #defines).
-
-The versions in include/ were generated as follows:
-
-  % cd <dir-where-you-cloned-freetype-to>
-  % bash autogen.sh
-  % ./configure
-  % cp objs/ftmodule.h ../include
-  % cp builds/unix/ftconfig.h ../include
-  % git apply patches/freetype2_symbols_visbility.patch
-
-Then we disable modules in include/ftmodule.h, then apply the symbols visibility
-patch to define the FT_EXPORT and FT_EXPORT_DEF macros to work properly when
-building a linux shared lib.
diff --git a/third_party/freetype2/include/freetype-custom-config/ftconfig.h b/third_party/freetype2/include/freetype-custom-config/ftconfig.h
deleted file mode 100644
index 80e7940..0000000
--- a/third_party/freetype2/include/freetype-custom-config/ftconfig.h
+++ /dev/null
@@ -1,504 +0,0 @@
-/* ftconfig.h.  Generated from ftconfig.in by configure.  */
-/***************************************************************************/
-/*                                                                         */
-/*  ftconfig.in                                                            */
-/*                                                                         */
-/*    UNIX-specific configuration file (specification only).               */
-/*                                                                         */
-/*  Copyright 1996-2016 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* This header file contains a number of macro definitions that are used */
-  /* by the rest of the engine.  Most of the macros here are automatically */
-  /* determined at compile time, and you should not need to change it to   */
-  /* port FreeType, except to compile the library with a non-ANSI          */
-  /* compiler.                                                             */
-  /*                                                                       */
-  /* Note however that if some specific modifications are needed, we       */
-  /* advise you to place a modified copy in your build directory.          */
-  /*                                                                       */
-  /* The build directory is usually `builds/<system>', and contains        */
-  /* system-specific files that are always included first when building    */
-  /* the library.                                                          */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#ifndef FTCONFIG_H_
-#define FTCONFIG_H_
-
-#include <ft2build.h>
-#include FT_CONFIG_OPTIONS_H
-#include FT_CONFIG_STANDARD_LIBRARY_H
-
-
-FT_BEGIN_HEADER
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*               PLATFORM-SPECIFIC CONFIGURATION MACROS                  */
-  /*                                                                       */
-  /* These macros can be toggled to suit a specific system.  The current   */
-  /* ones are defaults used to compile FreeType in an ANSI C environment   */
-  /* (16bit compilers are also supported).  Copy this file to your own     */
-  /* `builds/<system>' directory, and edit it to port the engine.          */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#define HAVE_UNISTD_H 1
-#define HAVE_FCNTL_H 1
-#define HAVE_STDINT_H 1
-
-
-  /* There are systems (like the Texas Instruments 'C54x) where a `char' */
-  /* has 16 bits.  ANSI C says that sizeof(char) is always 1.  Since an  */
-  /* `int' has 16 bits also for this system, sizeof(int) gives 1 which   */
-  /* is probably unexpected.                                             */
-  /*                                                                     */
-  /* `CHAR_BIT' (defined in limits.h) gives the number of bits in a      */
-  /* `char' type.                                                        */
-
-#ifndef FT_CHAR_BIT
-#define FT_CHAR_BIT  CHAR_BIT
-#endif
-
-
-/* #undef FT_USE_AUTOCONF_SIZEOF_TYPES */
-#ifdef FT_USE_AUTOCONF_SIZEOF_TYPES
-
-#define SIZEOF_INT 4
-#define SIZEOF_LONG 8
-#define FT_SIZEOF_INT  SIZEOF_INT
-#define FT_SIZEOF_LONG SIZEOF_LONG
-
-#else /* !FT_USE_AUTOCONF_SIZEOF_TYPES */
-
-  /* Following cpp computation of the bit length of int and long */
-  /* is copied from default include/freetype/config/ftconfig.h.  */
-  /* If any improvement is required for this file, it should be  */
-  /* applied to the original header file for the builders that   */
-  /* do not use configure script.                                */
-
-  /* The size of an `int' type.  */
-#if                                 FT_UINT_MAX == 0xFFFFUL
-#define FT_SIZEOF_INT  (16 / FT_CHAR_BIT)
-#elif                               FT_UINT_MAX == 0xFFFFFFFFUL
-#define FT_SIZEOF_INT  (32 / FT_CHAR_BIT)
-#elif FT_UINT_MAX > 0xFFFFFFFFUL && FT_UINT_MAX == 0xFFFFFFFFFFFFFFFFUL
-#define FT_SIZEOF_INT  (64 / FT_CHAR_BIT)
-#else
-#error "Unsupported size of `int' type!"
-#endif
-
-  /* The size of a `long' type.  A five-byte `long' (as used e.g. on the */
-  /* DM642) is recognized but avoided.                                   */
-#if                                  FT_ULONG_MAX == 0xFFFFFFFFUL
-#define FT_SIZEOF_LONG  (32 / FT_CHAR_BIT)
-#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFUL
-#define FT_SIZEOF_LONG  (32 / FT_CHAR_BIT)
-#elif FT_ULONG_MAX > 0xFFFFFFFFUL && FT_ULONG_MAX == 0xFFFFFFFFFFFFFFFFUL
-#define FT_SIZEOF_LONG  (64 / FT_CHAR_BIT)
-#else
-#error "Unsupported size of `long' type!"
-#endif
-
-#endif /* !FT_USE_AUTOCONF_SIZEOF_TYPES */
-
-
-  /* FT_UNUSED is a macro used to indicate that a given parameter is not  */
-  /* used -- this is only used to get rid of unpleasant compiler warnings */
-#ifndef FT_UNUSED
-#define FT_UNUSED( arg )  ( (arg) = (arg) )
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*                     AUTOMATIC CONFIGURATION MACROS                    */
-  /*                                                                       */
-  /* These macros are computed from the ones defined above.  Don't touch   */
-  /* their definition, unless you know precisely what you are doing.  No   */
-  /* porter should need to mess with them.                                 */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Mac support                                                           */
-  /*                                                                       */
-  /*   This is the only necessary change, so it is defined here instead    */
-  /*   providing a new configuration file.                                 */
-  /*                                                                       */
-#if defined( __APPLE__ ) || ( defined( __MWERKS__ ) && defined( macintosh ) )
-  /* no Carbon frameworks for 64bit 10.4.x */
-  /* AvailabilityMacros.h is available since Mac OS X 10.2,        */
-  /* so guess the system version by maximum errno before inclusion */
-#include <errno.h>
-#ifdef ECANCELED /* defined since 10.2 */
-#include "AvailabilityMacros.h"
-#endif
-#if defined( __LP64__ ) && \
-    ( MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 )
-#undef FT_MACINTOSH
-#endif
-
-#elif defined( __SC__ ) || defined( __MRC__ )
-  /* Classic MacOS compilers */
-#include "ConditionalMacros.h"
-#if TARGET_OS_MAC
-#define FT_MACINTOSH 1
-#endif
-
-#endif
-
-
-  /* Fix compiler warning with sgi compiler */
-#if defined( __sgi ) && !defined( __GNUC__ )
-#if defined( _COMPILER_VERSION ) && ( _COMPILER_VERSION >= 730 )
-#pragma set woff 3505
-#endif
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Section>                                                             */
-  /*    basic_types                                                        */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Int16                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for a 16bit signed integer type.                         */
-  /*                                                                       */
-  typedef signed short  FT_Int16;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_UInt16                                                          */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for a 16bit unsigned integer type.                       */
-  /*                                                                       */
-  typedef unsigned short  FT_UInt16;
-
-  /* */
-
-
-  /* this #if 0 ... #endif clause is for documentation purposes */
-#if 0
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Int32                                                           */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    A typedef for a 32bit signed integer type.  The size depends on    */
-  /*    the configuration.                                                 */
-  /*                                                                       */
-  typedef signed XXX  FT_Int32;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_UInt32                                                          */
-  /*                                                                       */
-  /*    A typedef for a 32bit unsigned integer type.  The size depends on  */
-  /*    the configuration.                                                 */
-  /*                                                                       */
-  typedef unsigned XXX  FT_UInt32;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_Int64                                                           */
-  /*                                                                       */
-  /*    A typedef for a 64bit signed integer type.  The size depends on    */
-  /*    the configuration.  Only defined if there is real 64bit support;   */
-  /*    otherwise, it gets emulated with a structure (if necessary).       */
-  /*                                                                       */
-  typedef signed XXX  FT_Int64;
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Type>                                                                */
-  /*    FT_UInt64                                                          */
-  /*                                                                       */
-  /*    A typedef for a 64bit unsigned integer type.  The size depends on  */
-  /*    the configuration.  Only defined if there is real 64bit support;   */
-  /*    otherwise, it gets emulated with a structure (if necessary).       */
-  /*                                                                       */
-  typedef unsigned XXX  FT_UInt64;
-
-  /* */
-
-#endif
-
-#if FT_SIZEOF_INT == 4
-
-  typedef signed int      FT_Int32;
-  typedef unsigned int    FT_UInt32;
-
-#elif FT_SIZEOF_LONG == 4
-
-  typedef signed long     FT_Int32;
-  typedef unsigned long   FT_UInt32;
-
-#else
-#error "no 32bit type found -- please check your configuration files"
-#endif
-
-
-  /* look up an integer type that is at least 32 bits */
-#if FT_SIZEOF_INT >= 4
-
-  typedef int            FT_Fast;
-  typedef unsigned int   FT_UFast;
-
-#elif FT_SIZEOF_LONG >= 4
-
-  typedef long           FT_Fast;
-  typedef unsigned long  FT_UFast;
-
-#endif
-
-
-  /* determine whether we have a 64-bit int type for platforms without */
-  /* Autoconf                                                          */
-#if FT_SIZEOF_LONG == 8
-
-  /* FT_LONG64 must be defined if a 64-bit type is available */
-#define FT_LONG64
-#define FT_INT64   long
-#define FT_UINT64  unsigned long
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* A 64-bit data type may create compilation problems if you compile     */
-  /* in strict ANSI mode.  To avoid them, we disable other 64-bit data     */
-  /* types if __STDC__ is defined.  You can however ignore this rule       */
-  /* by defining the FT_CONFIG_OPTION_FORCE_INT64 configuration macro.     */
-  /*                                                                       */
-#elif !defined( __STDC__ ) || defined( FT_CONFIG_OPTION_FORCE_INT64 )
-
-#if defined( __STDC_VERSION__ ) && __STDC_VERSION__ >= 199901L
-
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-#elif defined( _MSC_VER ) && _MSC_VER >= 900  /* Visual C++ (and Intel C++) */
-
-  /* this compiler provides the __int64 type */
-#define FT_LONG64
-#define FT_INT64   __int64
-#define FT_UINT64  unsigned __int64
-
-#elif defined( __BORLANDC__ )  /* Borland C++ */
-
-  /* XXXX: We should probably check the value of __BORLANDC__ in order */
-  /*       to test the compiler version.                               */
-
-  /* this compiler provides the __int64 type */
-#define FT_LONG64
-#define FT_INT64   __int64
-#define FT_UINT64  unsigned __int64
-
-#elif defined( __WATCOMC__ )   /* Watcom C++ */
-
-  /* Watcom doesn't provide 64-bit data types */
-
-#elif defined( __MWERKS__ )    /* Metrowerks CodeWarrior */
-
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-#elif defined( __GNUC__ )
-
-  /* GCC provides the `long long' type */
-#define FT_LONG64
-#define FT_INT64   long long int
-#define FT_UINT64  unsigned long long int
-
-#endif /* __STDC_VERSION__ >= 199901L */
-
-#endif /* FT_SIZEOF_LONG == 8 */
-
-#ifdef FT_LONG64
-  typedef FT_INT64   FT_Int64;
-  typedef FT_UINT64  FT_UInt64;
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* miscellaneous                                                         */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-#define FT_BEGIN_STMNT  do {
-#define FT_END_STMNT    } while ( 0 )
-#define FT_DUMMY_STMNT  FT_BEGIN_STMNT FT_END_STMNT
-
-
-  /* typeof condition taken from gnulib's `intprops.h' header file */
-#if ( __GNUC__ >= 2                         || \
-      defined( __IBM__TYPEOF__ )            || \
-      ( __SUNPRO_C >= 0x5110 && !__STDC__ ) )
-#define FT_TYPEOF( type )  (__typeof__ (type))
-#else
-#define FT_TYPEOF( type )  /* empty */
-#endif
-
-
-#ifdef FT_MAKE_OPTION_SINGLE_OBJECT
-
-#define FT_LOCAL( x )      static  x
-#define FT_LOCAL_DEF( x )  static  x
-
-#else
-
-#ifdef __cplusplus
-#define FT_LOCAL( x )      extern "C"  x
-#define FT_LOCAL_DEF( x )  extern "C"  x
-#else
-#define FT_LOCAL( x )      extern  x
-#define FT_LOCAL_DEF( x )  x
-#endif
-
-#endif /* FT_MAKE_OPTION_SINGLE_OBJECT */
-
-#define FT_LOCAL_ARRAY( x )      extern const  x
-#define FT_LOCAL_ARRAY_DEF( x )  const  x
-
-
-#ifndef FT_BASE
-
-#ifdef __cplusplus
-#define FT_BASE( x )  extern "C"  x
-#else
-#define FT_BASE( x )  extern  x
-#endif
-
-#endif /* !FT_BASE */
-
-
-#ifndef FT_BASE_DEF
-
-#ifdef __cplusplus
-#define FT_BASE_DEF( x )  x
-#else
-#define FT_BASE_DEF( x )  x
-#endif
-
-#endif /* !FT_BASE_DEF */
-
-
-#ifndef FT_EXPORT
-
-#ifdef __cplusplus
-#define FT_EXPORT( x )  __attribute__ ((visibility ("default"))) extern "C"  x
-#else
-#define FT_EXPORT( x )  __attribute__ ((visibility ("default"))) extern  x
-#endif
-
-#endif /* !FT_EXPORT */
-
-
-#ifndef FT_EXPORT_DEF
-
-#ifdef __cplusplus
-#define FT_EXPORT_DEF( x )  __attribute__((visibility("default"))) extern "C"  x
-#else
-#define FT_EXPORT_DEF( x )  __attribute__((visibility("default"))) extern  x
-#endif
-
-#endif /* !FT_EXPORT_DEF */
-
-
-#ifndef FT_EXPORT_VAR
-
-#ifdef __cplusplus
-#define FT_EXPORT_VAR( x )  extern "C"  x
-#else
-#define FT_EXPORT_VAR( x )  extern  x
-#endif
-
-#endif /* !FT_EXPORT_VAR */
-
-  /* The following macros are needed to compile the library with a   */
-  /* C++ compiler and with 16bit compilers.                          */
-  /*                                                                 */
-
-  /* This is special.  Within C++, you must specify `extern "C"' for */
-  /* functions which are used via function pointers, and you also    */
-  /* must do that for structures which contain function pointers to  */
-  /* assure C linkage -- it's not possible to have (local) anonymous */
-  /* functions which are accessed by (global) function pointers.     */
-  /*                                                                 */
-  /*                                                                 */
-  /* FT_CALLBACK_DEF is used to _define_ a callback function.        */
-  /*                                                                 */
-  /* FT_CALLBACK_TABLE is used to _declare_ a constant variable that */
-  /* contains pointers to callback functions.                        */
-  /*                                                                 */
-  /* FT_CALLBACK_TABLE_DEF is used to _define_ a constant variable   */
-  /* that contains pointers to callback functions.                   */
-  /*                                                                 */
-  /*                                                                 */
-  /* Some 16bit compilers have to redefine these macros to insert    */
-  /* the infamous `_cdecl' or `__fastcall' declarations.             */
-  /*                                                                 */
-#ifndef FT_CALLBACK_DEF
-#ifdef __cplusplus
-#define FT_CALLBACK_DEF( x )  extern "C"  x
-#else
-#define FT_CALLBACK_DEF( x )  static  x
-#endif
-#endif /* FT_CALLBACK_DEF */
-
-#ifndef FT_CALLBACK_TABLE
-#ifdef __cplusplus
-#define FT_CALLBACK_TABLE      extern "C"
-#define FT_CALLBACK_TABLE_DEF  extern "C"
-#else
-#define FT_CALLBACK_TABLE      extern
-#define FT_CALLBACK_TABLE_DEF  /* nothing */
-#endif
-#endif /* FT_CALLBACK_TABLE */
-
-
-FT_END_HEADER
-
-
-#endif /* FTCONFIG_H_ */
-
-
-/* END */
diff --git a/third_party/freetype2/include/freetype-custom-config/ftmodule.h b/third_party/freetype2/include/freetype-custom-config/ftmodule.h
deleted file mode 100644
index 8ec70b80..0000000
--- a/third_party/freetype2/include/freetype-custom-config/ftmodule.h
+++ /dev/null
@@ -1,38 +0,0 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftmodule.h                                                             */
-/*                                                                         */
-/*    User-selectable module macros.                                       */
-/*                                                                         */
-/*  Copyright 1996-2015 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-FT_USE_MODULE( FT_Module_Class, autofit_module_class )
-FT_USE_MODULE( FT_Driver_ClassRec, tt_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, cff_driver_class )
-FT_USE_MODULE( FT_Module_Class, psnames_module_class )
-FT_USE_MODULE( FT_Module_Class, pshinter_module_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_raster1_renderer_class )
-FT_USE_MODULE( FT_Module_Class, sfnt_module_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_smooth_renderer_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcd_renderer_class )
-FT_USE_MODULE( FT_Renderer_Class, ft_smooth_lcdv_renderer_class )
-
-/*
-FT_USE_MODULE( FT_Driver_ClassRec, t1_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, t1cid_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, pfr_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, t42_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, winfnt_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, pcf_driver_class )
-FT_USE_MODULE( FT_Driver_ClassRec, bdf_driver_class )
-FT_USE_MODULE( FT_Module_Class, psaux_module_class )
-*/
diff --git a/third_party/freetype2/include/freetype-custom-config/ftoption.h b/third_party/freetype2/include/freetype-custom-config/ftoption.h
deleted file mode 100644
index e2d22a87..0000000
--- a/third_party/freetype2/include/freetype-custom-config/ftoption.h
+++ /dev/null
@@ -1,969 +0,0 @@
-/***************************************************************************/
-/*                                                                         */
-/*  ftoption.h                                                             */
-/*                                                                         */
-/*    User-selectable configuration macros (specification only).           */
-/*                                                                         */
-/*  Copyright 1996-2017 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
-
-
-#ifndef FTOPTION_H_
-#define FTOPTION_H_
-
-
-#include <ft2build.h>
-
-
-FT_BEGIN_HEADER
-
-  /*************************************************************************/
-  /*                                                                       */
-  /*                 USER-SELECTABLE CONFIGURATION MACROS                  */
-  /*                                                                       */
-  /* This file contains the default configuration macro definitions for    */
-  /* a standard build of the FreeType library.  There are three ways to    */
-  /* use this file to build project-specific versions of the library:      */
-  /*                                                                       */
-  /*  - You can modify this file by hand, but this is not recommended in   */
-  /*    cases where you would like to build several versions of the        */
-  /*    library from a single source directory.                            */
-  /*                                                                       */
-  /*  - You can put a copy of this file in your build directory, more      */
-  /*    precisely in `$BUILD/freetype/config/ftoption.h', where `$BUILD'   */
-  /*    is the name of a directory that is included _before_ the FreeType  */
-  /*    include path during compilation.                                   */
-  /*                                                                       */
-  /*    The default FreeType Makefiles and Jamfiles use the build          */
-  /*    directory `builds/<system>' by default, but you can easily change  */
-  /*    that for your own projects.                                        */
-  /*                                                                       */
-  /*  - Copy the file <ft2build.h> to `$BUILD/ft2build.h' and modify it    */
-  /*    slightly to pre-define the macro FT_CONFIG_OPTIONS_H used to       */
-  /*    locate this file during the build.  For example,                   */
-  /*                                                                       */
-  /*      #define FT_CONFIG_OPTIONS_H  <myftoptions.h>                     */
-  /*      #include <freetype/config/ftheader.h>                            */
-  /*                                                                       */
-  /*    will use `$BUILD/myftoptions.h' instead of this file for macro     */
-  /*    definitions.                                                       */
-  /*                                                                       */
-  /*    Note also that you can similarly pre-define the macro              */
-  /*    FT_CONFIG_MODULES_H used to locate the file listing of the modules */
-  /*    that are statically linked to the library at compile time.  By     */
-  /*    default, this file is <freetype/config/ftmodule.h>.                */
-  /*                                                                       */
-  /* We highly recommend using the third method whenever possible.         */
-  /*                                                                       */
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /**** G E N E R A L   F R E E T Y P E   2   C O N F I G U R A T I O N ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* If you enable this configuration option, FreeType recognizes an       */
-  /* environment variable called `FREETYPE_PROPERTIES', which can be used  */
-  /* to control the various font drivers and modules.  The controllable    */
-  /* properties are listed in the section `Controlling FreeType Modules'   */
-  /* in the reference's table of contents; currently there are properties  */
-  /* for the auto-hinter (file `ftautoh.h'), CFF (file `ftcffdrv.h'),      */
-  /* TrueType (file `ftttdrv.h'), and PCF (file `ftpcfdrv.h').             */
-  /*                                                                       */
-  /* `FREETYPE_PROPERTIES' has the following syntax form (broken here into */
-  /* multiple lines for better readability).                               */
-  /*                                                                       */
-  /*   <optional whitespace>                                               */
-  /*   <module-name1> ':'                                                  */
-  /*   <property-name1> '=' <property-value1>                              */
-  /*   <whitespace>                                                        */
-  /*   <module-name2> ':'                                                  */
-  /*   <property-name2> '=' <property-value2>                              */
-  /*   ...                                                                 */
-  /*                                                                       */
-  /* Example:                                                              */
-  /*                                                                       */
-  /*   FREETYPE_PROPERTIES=truetype:interpreter-version=35 \               */
-  /*                       cff:no-stem-darkening=1 \                       */
-  /*                       autofitter:warping=1                            */
-  /*                                                                       */
-/*#define FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES*/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Uncomment the line below if you want to activate sub-pixel rendering  */
-  /* (a.k.a. LCD rendering, or ClearType) in this build of the library.    */
-  /*                                                                       */
-  /* Note that this feature is covered by several Microsoft patents        */
-  /* and should not be activated in any default build of the library.      */
-  /*                                                                       */
-  /* This macro has no impact on the FreeType API, only on its             */
-  /* _implementation_.  For example, using FT_RENDER_MODE_LCD when calling */
-  /* FT_Render_Glyph still generates a bitmap that is 3 times wider than   */
-  /* the original size in case this macro isn't defined; however, each     */
-  /* triplet of subpixels has R=G=B.                                       */
-  /*                                                                       */
-  /* This is done to allow FreeType clients to run unmodified, forcing     */
-  /* them to display normal gray-level anti-aliased glyphs.                */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_SUBPIXEL_RENDERING */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Many compilers provide a non-ANSI 64-bit data type that can be used   */
-  /* by FreeType to speed up some computations.  However, this will create */
-  /* some problems when compiling the library in strict ANSI mode.         */
-  /*                                                                       */
-  /* For this reason, the use of 64-bit integers is normally disabled when */
-  /* the __STDC__ macro is defined.  You can however disable this by       */
-  /* defining the macro FT_CONFIG_OPTION_FORCE_INT64 here.                 */
-  /*                                                                       */
-  /* For most compilers, this will only create compilation warnings when   */
-  /* building the library.                                                 */
-  /*                                                                       */
-  /* ObNote: The compiler-specific 64-bit integers are detected in the     */
-  /*         file `ftconfig.h' either statically or through the            */
-  /*         `configure' script on supported platforms.                    */
-  /*                                                                       */
-#undef FT_CONFIG_OPTION_FORCE_INT64
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* If this macro is defined, do not try to use an assembler version of   */
-  /* performance-critical functions (e.g. FT_MulFix).  You should only do  */
-  /* that to verify that the assembler function works properly, or to      */
-  /* execute benchmark tests of the various implementations.               */
-/* #define FT_CONFIG_OPTION_NO_ASSEMBLER */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* If this macro is defined, try to use an inlined assembler version of  */
-  /* the `FT_MulFix' function, which is a `hotspot' when loading and       */
-  /* hinting glyphs, and which should be executed as fast as possible.     */
-  /*                                                                       */
-  /* Note that if your compiler or CPU is not supported, this will default */
-  /* to the standard and portable implementation found in `ftcalc.c'.      */
-  /*                                                                       */
-#define FT_CONFIG_OPTION_INLINE_MULFIX
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* LZW-compressed file support.                                          */
-  /*                                                                       */
-  /*   FreeType now handles font files that have been compressed with the  */
-  /*   `compress' program.  This is mostly used to parse many of the PCF   */
-  /*   files that come with various X11 distributions.  The implementation */
-  /*   uses NetBSD's `zopen' to partially uncompress the file on the fly   */
-  /*   (see src/lzw/ftgzip.c).                                             */
-  /*                                                                       */
-  /*   Define this macro if you want to enable this `feature'.             */
-  /*                                                                       */
-#define FT_CONFIG_OPTION_USE_LZW
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Gzip-compressed file support.                                         */
-  /*                                                                       */
-  /*   FreeType now handles font files that have been compressed with the  */
-  /*   `gzip' program.  This is mostly used to parse many of the PCF files */
-  /*   that come with XFree86.  The implementation uses `zlib' to          */
-  /*   partially uncompress the file on the fly (see src/gzip/ftgzip.c).   */
-  /*                                                                       */
-  /*   Define this macro if you want to enable this `feature'.  See also   */
-  /*   the macro FT_CONFIG_OPTION_SYSTEM_ZLIB below.                       */
-  /*                                                                       */
-#define FT_CONFIG_OPTION_USE_ZLIB
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* ZLib library selection                                                */
-  /*                                                                       */
-  /*   This macro is only used when FT_CONFIG_OPTION_USE_ZLIB is defined.  */
-  /*   It allows FreeType's `ftgzip' component to link to the system's     */
-  /*   installation of the ZLib library.  This is useful on systems like   */
-  /*   Unix or VMS where it generally is already available.                */
-  /*                                                                       */
-  /*   If you let it undefined, the component will use its own copy        */
-  /*   of the zlib sources instead.  These have been modified to be        */
-  /*   included directly within the component and *not* export external    */
-  /*   function names.  This allows you to link any program with FreeType  */
-  /*   _and_ ZLib without linking conflicts.                               */
-  /*                                                                       */
-  /*   Do not #undef this macro here since the build system might define   */
-  /*   it for certain configurations only.                                 */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_SYSTEM_ZLIB */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Bzip2-compressed file support.                                        */
-  /*                                                                       */
-  /*   FreeType now handles font files that have been compressed with the  */
-  /*   `bzip2' program.  This is mostly used to parse many of the PCF      */
-  /*   files that come with XFree86.  The implementation uses `libbz2' to  */
-  /*   partially uncompress the file on the fly (see src/bzip2/ftbzip2.c). */
-  /*   Contrary to gzip, bzip2 currently is not included and need to use   */
-  /*   the system available bzip2 implementation.                          */
-  /*                                                                       */
-  /*   Define this macro if you want to enable this `feature'.             */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_USE_BZIP2 */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define to disable the use of file stream functions and types, FILE,   */
-  /* fopen() etc.  Enables the use of smaller system libraries on embedded */
-  /* systems that have multiple system libraries, some with or without     */
-  /* file stream support, in the cases where file stream support is not    */
-  /* necessary such as memory loading of font files.                       */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_DISABLE_STREAM_SUPPORT */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* PNG bitmap support.                                                   */
-  /*                                                                       */
-  /*   FreeType now handles loading color bitmap glyphs in the PNG format. */
-  /*   This requires help from the external libpng library.  Uncompressed  */
-  /*   color bitmaps do not need any external libraries and will be        */
-  /*   supported regardless of this configuration.                         */
-  /*                                                                       */
-  /*   Define this macro if you want to enable this `feature'.             */
-  /*                                                                       */
-#define FT_CONFIG_OPTION_USE_PNG
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* HarfBuzz support.                                                     */
-  /*                                                                       */
-  /*   FreeType uses the HarfBuzz library to improve auto-hinting of       */
-  /*   OpenType fonts.  If available, many glyphs not directly addressable */
-  /*   by a font's character map will be hinted also.                      */
-  /*                                                                       */
-  /*   Define this macro if you want to enable this `feature'.             */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_USE_HARFBUZZ */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* DLL export compilation                                                */
-  /*                                                                       */
-  /*   When compiling FreeType as a DLL, some systems/compilers need a     */
-  /*   special keyword in front OR after the return type of function       */
-  /*   declarations.                                                       */
-  /*                                                                       */
-  /*   Two macros are used within the FreeType source code to define       */
-  /*   exported library functions: FT_EXPORT and FT_EXPORT_DEF.            */
-  /*                                                                       */
-  /*     FT_EXPORT( return_type )                                          */
-  /*                                                                       */
-  /*       is used in a function declaration, as in                        */
-  /*                                                                       */
-  /*         FT_EXPORT( FT_Error )                                         */
-  /*         FT_Init_FreeType( FT_Library*  alibrary );                    */
-  /*                                                                       */
-  /*                                                                       */
-  /*     FT_EXPORT_DEF( return_type )                                      */
-  /*                                                                       */
-  /*       is used in a function definition, as in                         */
-  /*                                                                       */
-  /*         FT_EXPORT_DEF( FT_Error )                                     */
-  /*         FT_Init_FreeType( FT_Library*  alibrary )                     */
-  /*         {                                                             */
-  /*           ... some code ...                                           */
-  /*           return FT_Err_Ok;                                           */
-  /*         }                                                             */
-  /*                                                                       */
-  /*   You can provide your own implementation of FT_EXPORT and            */
-  /*   FT_EXPORT_DEF here if you want.  If you leave them undefined, they  */
-  /*   will be later automatically defined as `extern return_type' to      */
-  /*   allow normal compilation.                                           */
-  /*                                                                       */
-  /*   Do not #undef these macros here since the build system might define */
-  /*   them for certain configurations only.                               */
-  /*                                                                       */
-/* #define FT_EXPORT(x)      extern x */
-/* #define FT_EXPORT_DEF(x)  x */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Glyph Postscript Names handling                                       */
-  /*                                                                       */
-  /*   By default, FreeType 2 is compiled with the `psnames' module.  This */
-  /*   module is in charge of converting a glyph name string into a        */
-  /*   Unicode value, or return a Macintosh standard glyph name for the    */
-  /*   use with the TrueType `post' table.                                 */
-  /*                                                                       */
-  /*   Undefine this macro if you do not want `psnames' compiled in your   */
-  /*   build of FreeType.  This has the following effects:                 */
-  /*                                                                       */
-  /*   - The TrueType driver will provide its own set of glyph names,      */
-  /*     if you build it to support postscript names in the TrueType       */
-  /*     `post' table.                                                     */
-  /*                                                                       */
-  /*   - The Type 1 driver will not be able to synthesize a Unicode        */
-  /*     charmap out of the glyphs found in the fonts.                     */
-  /*                                                                       */
-  /*   You would normally undefine this configuration macro when building  */
-  /*   a version of FreeType that doesn't contain a Type 1 or CFF driver.  */
-  /*                                                                       */
-#define FT_CONFIG_OPTION_POSTSCRIPT_NAMES
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Postscript Names to Unicode Values support                            */
-  /*                                                                       */
-  /*   By default, FreeType 2 is built with the `PSNames' module compiled  */
-  /*   in.  Among other things, the module is used to convert a glyph name */
-  /*   into a Unicode value.  This is especially useful in order to        */
-  /*   synthesize on the fly a Unicode charmap from the CFF/Type 1 driver  */
-  /*   through a big table named the `Adobe Glyph List' (AGL).             */
-  /*                                                                       */
-  /*   Undefine this macro if you do not want the Adobe Glyph List         */
-  /*   compiled in your `PSNames' module.  The Type 1 driver will not be   */
-  /*   able to synthesize a Unicode charmap out of the glyphs found in the */
-  /*   fonts.                                                              */
-  /*                                                                       */
-#define FT_CONFIG_OPTION_ADOBE_GLYPH_LIST
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Support for Mac fonts                                                 */
-  /*                                                                       */
-  /*   Define this macro if you want support for outline fonts in Mac      */
-  /*   format (mac dfont, mac resource, macbinary containing a mac         */
-  /*   resource) on non-Mac platforms.                                     */
-  /*                                                                       */
-  /*   Note that the `FOND' resource isn't checked.                        */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_MAC_FONTS */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Guessing methods to access embedded resource forks                    */
-  /*                                                                       */
-  /*   Enable extra Mac fonts support on non-Mac platforms (e.g.           */
-  /*   GNU/Linux).                                                         */
-  /*                                                                       */
-  /*   Resource forks which include fonts data are stored sometimes in     */
-  /*   locations which users or developers don't expected.  In some cases, */
-  /*   resource forks start with some offset from the head of a file.  In  */
-  /*   other cases, the actual resource fork is stored in file different   */
-  /*   from what the user specifies.  If this option is activated,         */
-  /*   FreeType tries to guess whether such offsets or different file      */
-  /*   names must be used.                                                 */
-  /*                                                                       */
-  /*   Note that normal, direct access of resource forks is controlled via */
-  /*   the FT_CONFIG_OPTION_MAC_FONTS option.                              */
-  /*                                                                       */
-#ifdef FT_CONFIG_OPTION_MAC_FONTS
-#define FT_CONFIG_OPTION_GUESSING_EMBEDDED_RFORK
-#endif
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Allow the use of FT_Incremental_Interface to load typefaces that      */
-  /* contain no glyph data, but supply it via a callback function.         */
-  /* This is required by clients supporting document formats which         */
-  /* supply font data incrementally as the document is parsed, such        */
-  /* as the Ghostscript interpreter for the PostScript language.           */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_INCREMENTAL */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* The size in bytes of the render pool used by the scan-line converter  */
-  /* to do all of its work.                                                */
-  /*                                                                       */
-#define FT_RENDER_POOL_SIZE  16384L
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* FT_MAX_MODULES                                                        */
-  /*                                                                       */
-  /*   The maximum number of modules that can be registered in a single    */
-  /*   FreeType library object.  32 is the default.                        */
-  /*                                                                       */
-#define FT_MAX_MODULES  32
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Debug level                                                           */
-  /*                                                                       */
-  /*   FreeType can be compiled in debug or trace mode.  In debug mode,    */
-  /*   errors are reported through the `ftdebug' component.  In trace      */
-  /*   mode, additional messages are sent to the standard output during    */
-  /*   execution.                                                          */
-  /*                                                                       */
-  /*   Define FT_DEBUG_LEVEL_ERROR to build the library in debug mode.     */
-  /*   Define FT_DEBUG_LEVEL_TRACE to build it in trace mode.              */
-  /*                                                                       */
-  /*   Don't define any of these macros to compile in `release' mode!      */
-  /*                                                                       */
-  /*   Do not #undef these macros here since the build system might define */
-  /*   them for certain configurations only.                               */
-  /*                                                                       */
-/* #define FT_DEBUG_LEVEL_ERROR */
-/* #define FT_DEBUG_LEVEL_TRACE */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Autofitter debugging                                                  */
-  /*                                                                       */
-  /*   If FT_DEBUG_AUTOFIT is defined, FreeType provides some means to     */
-  /*   control the autofitter behaviour for debugging purposes with global */
-  /*   boolean variables (consequently, you should *never* enable this     */
-  /*   while compiling in `release' mode):                                 */
-  /*                                                                       */
-  /*     _af_debug_disable_horz_hints                                      */
-  /*     _af_debug_disable_vert_hints                                      */
-  /*     _af_debug_disable_blue_hints                                      */
-  /*                                                                       */
-  /*   Additionally, the following functions provide dumps of various      */
-  /*   internal autofit structures to stdout (using `printf'):             */
-  /*                                                                       */
-  /*     af_glyph_hints_dump_points                                        */
-  /*     af_glyph_hints_dump_segments                                      */
-  /*     af_glyph_hints_dump_edges                                         */
-  /*     af_glyph_hints_get_num_segments                                   */
-  /*     af_glyph_hints_get_segment_offset                                 */
-  /*                                                                       */
-  /*   As an argument, they use another global variable:                   */
-  /*                                                                       */
-  /*     _af_debug_hints                                                   */
-  /*                                                                       */
-  /*   Please have a look at the `ftgrid' demo program to see how those    */
-  /*   variables and macros should be used.                                */
-  /*                                                                       */
-  /*   Do not #undef these macros here since the build system might define */
-  /*   them for certain configurations only.                               */
-  /*                                                                       */
-/* #define FT_DEBUG_AUTOFIT */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Memory Debugging                                                      */
-  /*                                                                       */
-  /*   FreeType now comes with an integrated memory debugger that is       */
-  /*   capable of detecting simple errors like memory leaks or double      */
-  /*   deletes.  To compile it within your build of the library, you       */
-  /*   should define FT_DEBUG_MEMORY here.                                 */
-  /*                                                                       */
-  /*   Note that the memory debugger is only activated at runtime when     */
-  /*   when the _environment_ variable `FT2_DEBUG_MEMORY' is defined also! */
-  /*                                                                       */
-  /*   Do not #undef this macro here since the build system might define   */
-  /*   it for certain configurations only.                                 */
-  /*                                                                       */
-/* #define FT_DEBUG_MEMORY */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Module errors                                                         */
-  /*                                                                       */
-  /*   If this macro is set (which is _not_ the default), the higher byte  */
-  /*   of an error code gives the module in which the error has occurred,  */
-  /*   while the lower byte is the real error code.                        */
-  /*                                                                       */
-  /*   Setting this macro makes sense for debugging purposes only, since   */
-  /*   it would break source compatibility of certain programs that use    */
-  /*   FreeType 2.                                                         */
-  /*                                                                       */
-  /*   More details can be found in the files ftmoderr.h and fterrors.h.   */
-  /*                                                                       */
-#undef FT_CONFIG_OPTION_USE_MODULE_ERRORS
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Position Independent Code                                             */
-  /*                                                                       */
-  /*   If this macro is set (which is _not_ the default), FreeType2 will   */
-  /*   avoid creating constants that require address fixups.  Instead the  */
-  /*   constants will be moved into a struct and additional intialization  */
-  /*   code will be used.                                                  */
-  /*                                                                       */
-  /*   Setting this macro is needed for systems that prohibit address      */
-  /*   fixups, such as BREW.  [Note that standard compilers like gcc or    */
-  /*   clang handle PIC generation automatically; you don't have to set    */
-  /*   FT_CONFIG_OPTION_PIC, which is only necessary for very special      */
-  /*   compilers.]                                                         */
-  /*                                                                       */
-  /*   Note that FT_CONFIG_OPTION_PIC support is not available for all     */
-  /*   modules (see `modules.cfg' for a complete list).  For building with */
-  /*   FT_CONFIG_OPTION_PIC support, do the following.                     */
-  /*                                                                       */
-  /*     0. Clone the repository.                                          */
-  /*     1. Define FT_CONFIG_OPTION_PIC.                                   */
-  /*     2. Remove all subdirectories in `src' that don't have             */
-  /*        FT_CONFIG_OPTION_PIC support.                                  */
-  /*     3. Comment out the corresponding modules in `modules.cfg'.        */
-  /*     4. Compile.                                                       */
-  /*                                                                       */
-/* #define FT_CONFIG_OPTION_PIC */
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****        S F N T   D R I V E R    C O N F I G U R A T I O N       ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_EMBEDDED_BITMAPS if you want to support       */
-  /* embedded bitmaps in all formats using the SFNT module (namely         */
-  /* TrueType & OpenType).                                                 */
-  /*                                                                       */
-#define TT_CONFIG_OPTION_EMBEDDED_BITMAPS
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_POSTSCRIPT_NAMES if you want to be able to    */
-  /* load and enumerate the glyph Postscript names in a TrueType or        */
-  /* OpenType file.                                                        */
-  /*                                                                       */
-  /* Note that when you do not compile the `PSNames' module by undefining  */
-  /* the above FT_CONFIG_OPTION_POSTSCRIPT_NAMES, the `sfnt' module will   */
-  /* contain additional code used to read the PS Names table from a font.  */
-  /*                                                                       */
-  /* (By default, the module uses `PSNames' to extract glyph names.)       */
-  /*                                                                       */
-#define TT_CONFIG_OPTION_POSTSCRIPT_NAMES
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_SFNT_NAMES if your applications need to       */
-  /* access the internal name table in a SFNT-based format like TrueType   */
-  /* or OpenType.  The name table contains various strings used to         */
-  /* describe the font, like family name, copyright, version, etc.  It     */
-  /* does not contain any glyph name though.                               */
-  /*                                                                       */
-  /* Accessing SFNT names is done through the functions declared in        */
-  /* `ftsnames.h'.                                                         */
-  /*                                                                       */
-#define TT_CONFIG_OPTION_SFNT_NAMES
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* TrueType CMap support                                                 */
-  /*                                                                       */
-  /*   Here you can fine-tune which TrueType CMap table format shall be    */
-  /*   supported.                                                          */
-#define TT_CONFIG_CMAP_FORMAT_0
-#define TT_CONFIG_CMAP_FORMAT_2
-#define TT_CONFIG_CMAP_FORMAT_4
-#define TT_CONFIG_CMAP_FORMAT_6
-#define TT_CONFIG_CMAP_FORMAT_8
-#define TT_CONFIG_CMAP_FORMAT_10
-#define TT_CONFIG_CMAP_FORMAT_12
-#define TT_CONFIG_CMAP_FORMAT_13
-#define TT_CONFIG_CMAP_FORMAT_14
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****    T R U E T Y P E   D R I V E R    C O N F I G U R A T I O N   ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_BYTECODE_INTERPRETER if you want to compile   */
-  /* a bytecode interpreter in the TrueType driver.                        */
-  /*                                                                       */
-  /* By undefining this, you will only compile the code necessary to load  */
-  /* TrueType glyphs without hinting.                                      */
-  /*                                                                       */
-  /*   Do not #undef this macro here, since the build system might         */
-  /*   define it for certain configurations only.                          */
-  /*                                                                       */
-#define TT_CONFIG_OPTION_BYTECODE_INTERPRETER
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_SUBPIXEL_HINTING if you want to compile       */
-  /* subpixel hinting support into the TrueType driver.  This modifies the */
-  /* TrueType hinting mechanism when anything but FT_RENDER_MODE_MONO is   */
-  /* requested.                                                            */
-  /*                                                                       */
-  /* In particular, it modifies the bytecode interpreter to interpret (or  */
-  /* not) instructions in a certain way so that all TrueType fonts look    */
-  /* like they do in a Windows ClearType (DirectWrite) environment.  See   */
-  /* [1] for a technical overview on what this means.  See `ttinterp.h'    */
-  /* for more details on the LEAN option.                                  */
-  /*                                                                       */
-  /* There are three possible values.                                      */
-  /*                                                                       */
-  /* Value 1:                                                              */
-  /*    This value is associated with the `Infinality' moniker,            */
-  /*    contributed by an individual nicknamed Infinality with the goal of */
-  /*    making TrueType fonts render better than on Windows.  A high       */
-  /*    amount of configurability and flexibility, down to rules for       */
-  /*    single glyphs in fonts, but also very slow.  Its experimental and  */
-  /*    slow nature and the original developer losing interest meant that  */
-  /*    this option was never enabled in default builds.                   */
-  /*                                                                       */
-  /*    The corresponding interpreter version is v38.                      */
-  /*                                                                       */
-  /* Value 2:                                                              */
-  /*    The new default mode for the TrueType driver.  The Infinality code */
-  /*    base was stripped to the bare minimum and all configurability      */
-  /*    removed in the name of speed and simplicity.  The configurability  */
-  /*    was mainly aimed at legacy fonts like Arial, Times New Roman, or   */
-  /*    Courier.  Legacy fonts are fonts that modify vertical stems to     */
-  /*    achieve clean black-and-white bitmaps.  The new mode focuses on    */
-  /*    applying a minimal set of rules to all fonts indiscriminately so   */
-  /*    that modern and web fonts render well while legacy fonts render    */
-  /*    okay.                                                              */
-  /*                                                                       */
-  /*    The corresponding interpreter version is v40.                      */
-  /*                                                                       */
-  /* Value 3:                                                              */
-  /*    Compile both, making both v38 and v40 available (the latter is the */
-  /*    default).                                                          */
-  /*                                                                       */
-  /* By undefining these, you get rendering behavior like on Windows       */
-  /* without ClearType, i.e., Windows XP without ClearType enabled and     */
-  /* Win9x (interpreter version v35).  Or not, depending on how much       */
-  /* hinting blood and testing tears the font designer put into a given    */
-  /* font.  If you define one or both subpixel hinting options, you can    */
-  /* switch between between v35 and the ones you define (using             */
-  /* `FT_Property_Set').                                                   */
-  /*                                                                       */
-  /* This option requires TT_CONFIG_OPTION_BYTECODE_INTERPRETER to be      */
-  /* defined.                                                              */
-  /*                                                                       */
-  /* [1] http://www.microsoft.com/typography/cleartype/truetypecleartype.aspx */
-  /*                                                                       */
-/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  1         */
-#define TT_CONFIG_OPTION_SUBPIXEL_HINTING  2
-/* #define TT_CONFIG_OPTION_SUBPIXEL_HINTING  ( 1 | 2 ) */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED to compile the        */
-  /* TrueType glyph loader to use Apple's definition of how to handle      */
-  /* component offsets in composite glyphs.                                */
-  /*                                                                       */
-  /* Apple and MS disagree on the default behavior of component offsets    */
-  /* in composites.  Apple says that they should be scaled by the scaling  */
-  /* factors in the transformation matrix (roughly, it's more complex)     */
-  /* while MS says they should not.  OpenType defines two bits in the      */
-  /* composite flags array which can be used to disambiguate, but old      */
-  /* fonts will not have them.                                             */
-  /*                                                                       */
-  /*   http://www.microsoft.com/typography/otspec/glyf.htm                 */
-  /*   https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6glyf.html */
-  /*                                                                       */
-#undef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_GX_VAR_SUPPORT if you want to include         */
-  /* support for Apple's distortable font technology (fvar, gvar, cvar,    */
-  /* and avar tables).  This has many similarities to Type 1 Multiple      */
-  /* Masters support.                                                      */
-  /*                                                                       */
-#define TT_CONFIG_OPTION_GX_VAR_SUPPORT
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define TT_CONFIG_OPTION_BDF if you want to include support for        */
-  /* an embedded `BDF ' table within SFNT-based bitmap formats.            */
-  /*                                                                       */
-/* #define TT_CONFIG_OPTION_BDF */
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Option TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES controls the maximum     */
-  /* number of bytecode instructions executed for a single run of the      */
-  /* bytecode interpreter, needed to prevent infinite loops.  You don't    */
-  /* want to change this except for very special situations (e.g., making  */
-  /* a library fuzzer spend less time to handle broken fonts).             */
-  /*                                                                       */
-  /* It is not expected that this value is ever modified by a configuring  */
-  /* script; instead, it gets surrounded with #ifndef ... #endif so that   */
-  /* the value can be set as a preprocessor option on the compiler's       */
-  /* command line.                                                         */
-  /*                                                                       */
-#ifndef TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES
-#define TT_CONFIG_OPTION_MAX_RUNNABLE_OPCODES  1000000L
-#endif
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****      T Y P E 1   D R I V E R    C O N F I G U R A T I O N       ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* T1_MAX_DICT_DEPTH is the maximum depth of nest dictionaries and       */
-  /* arrays in the Type 1 stream (see t1load.c).  A minimum of 4 is        */
-  /* required.                                                             */
-  /*                                                                       */
-#define T1_MAX_DICT_DEPTH  5
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* T1_MAX_SUBRS_CALLS details the maximum number of nested sub-routine   */
-  /* calls during glyph loading.                                           */
-  /*                                                                       */
-#define T1_MAX_SUBRS_CALLS  16
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* T1_MAX_CHARSTRING_OPERANDS is the charstring stack's capacity.  A     */
-  /* minimum of 16 is required.                                            */
-  /*                                                                       */
-  /* The Chinese font MingTiEG-Medium (CNS 11643 character set) needs 256. */
-  /*                                                                       */
-#define T1_MAX_CHARSTRINGS_OPERANDS  256
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define this configuration macro if you want to prevent the            */
-  /* compilation of `t1afm', which is in charge of reading Type 1 AFM      */
-  /* files into an existing face.  Note that if set, the T1 driver will be */
-  /* unable to produce kerning distances.                                  */
-  /*                                                                       */
-#undef T1_CONFIG_OPTION_NO_AFM
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Define this configuration macro if you want to prevent the            */
-  /* compilation of the Multiple Masters font support in the Type 1        */
-  /* driver.                                                               */
-  /*                                                                       */
-#undef T1_CONFIG_OPTION_NO_MM_SUPPORT
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****         C F F   D R I V E R    C O N F I G U R A T I O N        ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Using CFF_CONFIG_OPTION_DARKENING_PARAMETER_{X,Y}{1,2,3,4} it is      */
-  /* possible to set up the default values of the four control points that */
-  /* define the stem darkening behaviour of the (new) CFF engine.  For     */
-  /* more details please read the documentation of the                     */
-  /* `darkening-parameters' property of the cff driver module (file        */
-  /* `ftcffdrv.h'), which allows the control at run-time.                  */
-  /*                                                                       */
-  /* Do *not* undefine these macros!                                       */
-  /*                                                                       */
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1   500
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1   400
-
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2  1000
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2   275
-
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3  1667
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3   275
-
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4  2333
-#define CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4     0
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* CFF_CONFIG_OPTION_OLD_ENGINE controls whether the pre-Adobe CFF       */
-  /* engine gets compiled into FreeType.  If defined, it is possible to    */
-  /* switch between the two engines using the `hinting-engine' property of */
-  /* the cff driver module.                                                */
-  /*                                                                       */
-/* #define CFF_CONFIG_OPTION_OLD_ENGINE */
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****         P C F   D R I V E R    C O N F I G U R A T I O N        ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* There are many PCF fonts just called `Fixed' which look completely    */
-  /* different, and which have nothing to do with each other.  When        */
-  /* selecting `Fixed' in KDE or Gnome one gets results that appear rather */
-  /* random, the style changes often if one changes the size and one       */
-  /* cannot select some fonts at all.  This option makes the PCF module    */
-  /* prepend the foundry name (plus a space) to the family name.           */
-  /*                                                                       */
-  /* We also check whether we have `wide' characters; all put together, we */
-  /* get family names like `Sony Fixed' or `Misc Fixed Wide'.              */
-  /*                                                                       */
-  /* If this option is activated, it can be controlled with the            */
-  /* `no-long-family-names' property of the pcf driver module.             */
-  /*                                                                       */
-/* #define PCF_CONFIG_OPTION_LONG_FAMILY_NAMES */
-
-
-  /*************************************************************************/
-  /*************************************************************************/
-  /****                                                                 ****/
-  /****    A U T O F I T   M O D U L E    C O N F I G U R A T I O N     ****/
-  /****                                                                 ****/
-  /*************************************************************************/
-  /*************************************************************************/
-
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Compile autofit module with CJK (Chinese, Japanese, Korean) script    */
-  /* support.                                                              */
-  /*                                                                       */
-#define AF_CONFIG_OPTION_CJK
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Compile autofit module with Indic script support.                     */
-  /*                                                                       */
-#define AF_CONFIG_OPTION_INDIC
-
-  /*************************************************************************/
-  /*                                                                       */
-  /* Compile autofit module with warp hinting.  The idea of the warping    */
-  /* code is to slightly scale and shift a glyph within a single dimension */
-  /* so that as much of its segments are aligned (more or less) on the     */
-  /* grid.  To find out the optimal scaling and shifting value, various    */
-  /* parameter combinations are tried and scored.                          */
-  /*                                                                       */
-  /* This experimental option is active only if the rendering mode is      */
-  /* FT_RENDER_MODE_LIGHT; you can switch warping on and off with the      */
-  /* `warping' property of the auto-hinter (see file `ftautoh.h' for more  */
-  /* information; by default it is switched off).                          */
-  /*                                                                       */
-/*#define AF_CONFIG_OPTION_USE_WARPER*/
-
-  /* */
-
-
-  /*
-   * This macro is obsolete.  Support has been removed in FreeType
-   * version 2.5.
-   */
-/* #define FT_CONFIG_OPTION_OLD_INTERNALS */
-
-
-  /*
-   * This macro is defined if native TrueType hinting is requested by the
-   * definitions above.
-   */
-#ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
-#define  TT_USE_BYTECODE_INTERPRETER
-
-#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 1
-#define  TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
-#endif
-
-#if TT_CONFIG_OPTION_SUBPIXEL_HINTING & 2
-#define  TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
-#endif
-#endif
-
-
-  /*
-   * Check CFF darkening parameters.  The checks are the same as in function
-   * `cff_property_set' in file `cffdrivr.c'.
-   */
-#if CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 < 0   || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 < 0   || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 < 0   || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4 < 0   || \
-                                                      \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 < 0   || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 < 0   || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 < 0   || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 < 0   || \
-                                                      \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X1 >        \
-      CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2     || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X2 >        \
-      CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3     || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_X3 >        \
-      CFF_CONFIG_OPTION_DARKENING_PARAMETER_X4     || \
-                                                      \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y1 > 500 || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y2 > 500 || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y3 > 500 || \
-    CFF_CONFIG_OPTION_DARKENING_PARAMETER_Y4 > 500
-#error "Invalid CFF darkening parameters!"
-#endif
-
-FT_END_HEADER
-
-
-#endif /* FTOPTION_H_ */
-
-
-/* END */
diff --git a/third_party/freetype2/patches/freetype2_symbols_visibility.patch b/third_party/freetype2/patches/freetype2_symbols_visibility.patch
deleted file mode 100644
index e8c3232..0000000
--- a/third_party/freetype2/patches/freetype2_symbols_visibility.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-diff --git a/third_party/freetype2/include/freetype-custom-config/ftconfig.h b/third_party/freetype2/include/freetype-custom-config/ftconfig.h
-index 0e1945b..80e7940 100644
---- a/third_party/freetype2/include/freetype-custom-config/ftconfig.h
-+++ b/third_party/freetype2/include/freetype-custom-config/ftconfig.h
-@@ -424,9 +424,9 @@ FT_BEGIN_HEADER
- #ifndef FT_EXPORT
-
- #ifdef __cplusplus
--#define FT_EXPORT( x )  extern "C"  x
-+#define FT_EXPORT( x )  __attribute__ ((visibility ("default"))) extern "C"  x
- #else
--#define FT_EXPORT( x )  extern  x
-+#define FT_EXPORT( x )  __attribute__ ((visibility ("default"))) extern  x
- #endif
-
- #endif /* !FT_EXPORT */
-@@ -435,9 +435,9 @@ FT_BEGIN_HEADER
- #ifndef FT_EXPORT_DEF
-
- #ifdef __cplusplus
--#define FT_EXPORT_DEF( x )  extern "C"  x
-+#define FT_EXPORT_DEF( x )  __attribute__((visibility("default"))) extern "C"  x
- #else
--#define FT_EXPORT_DEF( x )  extern  x
-+#define FT_EXPORT_DEF( x )  __attribute__((visibility("default"))) extern  x
- #endif
-
- #endif /* !FT_EXPORT_DEF */
diff --git a/third_party/instrumented_libraries/scripts/build_and_package.sh b/third_party/instrumented_libraries/scripts/build_and_package.sh
deleted file mode 100755
index 0de0c91..0000000
--- a/third_party/instrumented_libraries/scripts/build_and_package.sh
+++ /dev/null
@@ -1,87 +0,0 @@
-#!/bin/bash
-# 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.
-
-set -eu
-
-supported_build_types="msan-no-origins msan-chained-origins"
-supported_releases="precise trusty"
-ubuntu_release=$(lsb_release -cs)
-
-function show_help {
-  echo "Usage: build_and_package.sh <build_type>"
-  echo "Supported build types: all ${supported_build_types}"
-}
-
-function build_libraries {
-  local build_type=$1
-  case ${build_type} in
-    "msan-chained-origins")
-      local gyp_defines="msan=1 msan_track_origins=2"
-      ;;
-    "msan-no-origins")
-      local gyp_defines="msan=1 msan_track_origins=0"
-      ;;
-    *)
-      show_help
-      exit 1
-      ;;
-  esac
-  
-  local archive_name=${build_type}-${ubuntu_release}
-  local out_dir=out-${archive_name}
-
-  echo "Building instrumented libraries in ${out_dir}..."
-
-  rm -rf $out_dir
-  mkdir $out_dir
-
-  GYP_DEFINES="${gyp_defines} \
-               use_instrumented_libraries=1 instrumented_libraries_jobs=8" \
-  GYP_GENERATOR_FLAGS="output_dir=${out_dir}" \
-  gclient runhooks
-
-  ninja -j4 -C ${out_dir}/Release instrumented_libraries
-
-  echo "Creating archive ${archive_name}.tgz..."
-
-  files=$(ls -1 ${out_dir}/Release/instrumented_libraries)
-
-  tar zcf ${archive_name}.tgz -C ${out_dir}/Release/instrumented_libraries \
-      --exclude="?san/*.txt" ${files}
-
-  echo To upload, run:
-  echo upload_to_google_storage.py -b \
-       chromium-instrumented-libraries ${archive_name}.tgz
-  echo You should then commit the resulting .sha1 file.
-}
-
-if ! [[ "${supported_releases}" =~ ${ubuntu_release} ]]
-then
-  echo "Unsupported Ubuntu release: ${ubuntu_release}"
-  echo "Supported releases: ${supported_releases}"
-  exit 1
-fi
-
-if [ -z "${1-}" ]
-then
-  show_help
-  exit 0
-fi
-
-if ! [[ "all ${supported_build_types}" =~ $1 ]]
-then
-  show_help
-  exit 1
-fi
-if [ "$1" == "all" ]
-then
-  for build_type in ${supported_build_types}
-  do
-    build_libraries ${build_type}
-  done
-else
-  build_libraries $1
-fi
-
diff --git a/tools/chrome_proxy/webdriver/safebrowsing.py b/tools/chrome_proxy/webdriver/safebrowsing.py
new file mode 100644
index 0000000..cdfe2ec
--- /dev/null
+++ b/tools/chrome_proxy/webdriver/safebrowsing.py
@@ -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.
+
+import common
+from common import TestDriver
+from common import IntegrationTest
+from common import AndroidOnly
+from common import NotAndroid
+
+
+class SafeBrowsing(IntegrationTest):
+
+  @AndroidOnly
+  def testSafeBrowsingOn(self):
+    with TestDriver() as t:
+      t.AddChromeArg('--enable-spdy-proxy-auth')
+      t.LoadURL('http://testsafebrowsing.appspot.com/s/malware.html')
+      responses = t.GetHTTPResponses()
+      self.assertEqual(0, len(responses))
+
+  @NotAndroid
+  def testSafeBrowsingOff(self):
+    with TestDriver() as t:
+      t.AddChromeArg('--enable-spdy-proxy-auth')
+      t.LoadURL('http://testsafebrowsing.appspot.com/s/malware.html')
+      responses = t.GetHTTPResponses()
+      self.assertEqual(1, len(responses))
+      for response in responses:
+        self.assertHasChromeProxyViaHeader(response)
+
+if __name__ == '__main__':
+  IntegrationTest.RunAllTests()
diff --git a/tools/json_schema_compiler/cpp_bundle_generator.py b/tools/json_schema_compiler/cpp_bundle_generator.py
index 89501e2..88e0f36 100644
--- a/tools/json_schema_compiler/cpp_bundle_generator.py
+++ b/tools/json_schema_compiler/cpp_bundle_generator.py
@@ -147,15 +147,19 @@
         raise ValueError("Unsupported platform ifdef: %s" % platform.name)
     return ' || '.join(ifdefs)
 
-  def _GenerateRegisterFunctions(self, namespace_name, function):
+  def _GenerateRegistrationEntry(self, namespace_name, function):
     c = code.Code()
     function_ifdefs = self._GetPlatformIfdefs(function)
     if function_ifdefs is not None:
       c.Append("#if %s" % function_ifdefs, indent_level=0)
 
-    function_name = JsFunctionNameToClassName(namespace_name, function.name)
-    c.Append("registry->RegisterFunction<%sFunction>();" % (
-        function_name))
+    function_name = '%sFunction' % JsFunctionNameToClassName(
+        namespace_name, function.name)
+    c.Sblock('{')
+    c.Append('&NewExtensionFunction<%s>,' % function_name)
+    c.Append('%s::function_name(),' % function_name)
+    c.Append('%s::histogram_value(),' % function_name)
+    c.Eblock('},')
 
     if function_ifdefs is not None:
       c.Append("#endif  // %s" % function_ifdefs, indent_level=0)
@@ -166,6 +170,7 @@
     c.Append('// static')
     c.Sblock('void %s::RegisterAll(ExtensionFunctionRegistry* registry) {' %
              self._GenerateBundleClass('GeneratedFunctionRegistry'))
+    c.Sblock('constexpr ExtensionFunctionRegistry::FactoryEntry kEntries[] = {')
     for namespace in self._model.namespaces.values():
       namespace_ifdefs = self._GetPlatformIfdefs(namespace)
       if namespace_ifdefs is not None:
@@ -174,7 +179,7 @@
       for function in namespace.functions.values():
         if function.nocompile:
           continue
-        c.Concat(self._GenerateRegisterFunctions(namespace.name, function))
+        c.Concat(self._GenerateRegistrationEntry(namespace.name, function))
 
       for type_ in namespace.types.values():
         for function in type_.functions.values():
@@ -182,11 +187,15 @@
             continue
           namespace_types_name = JsFunctionNameToClassName(
                 namespace.name, type_.name)
-          c.Concat(self._GenerateRegisterFunctions(namespace_types_name,
+          c.Concat(self._GenerateRegistrationEntry(namespace_types_name,
                                                    function))
 
       if namespace_ifdefs is not None:
         c.Append("#endif  // %s" % namespace_ifdefs, indent_level=0)
+    c.Eblock("};")
+    c.Sblock("for (const auto& entry : kEntries) {")
+    c.Append("  registry->Register(entry);")
+    c.Eblock("}")
     c.Eblock("}")
     return c
 
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 6319b69..7264867 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -371,6 +371,14 @@
   </summary>
 </histogram>
 
+<histogram name="ActivityTracker.Collect.StabilityFileCount" units="count">
+  <owner>manzagop@chromium.org</owner>
+  <summary>
+    Number of files found during stability file collection. Logged each time the
+    stability file collection proceeds (at most once per launch).
+  </summary>
+</histogram>
+
 <histogram name="ActivityTracker.Collect.Status"
     enum="ActivityTrackerCollectStatus">
   <owner>manzagop@chromium.org</owner>
@@ -71891,7 +71899,7 @@
   <summary>The time from starting translation to the completion.</summary>
 </histogram>
 
-<histogram name="Translate.Translate">
+<histogram name="Translate.Translate" enum="BooleanTranslate">
   <owner>kenjibaheux@google.com</owner>
   <summary>
     The number of times the translate button was clicked in the translate
@@ -71956,6 +71964,21 @@
   </summary>
 </histogram>
 
+<histogram name="UKM.Entries.Dropped" enum="UkmDataDroppedReason">
+  <owner>holte@chromium.org</owner>
+  <owner>rkaplow@chromium.org</owner>
+  <summary>
+    Number of UKM entries that are dropped. Categorized by the cause of it being
+    dropped.
+  </summary>
+</histogram>
+
+<histogram name="UKM.Entries.SerializedCount">
+  <owner>holte@chromium.org</owner>
+  <owner>rkaplow@chromium.org</owner>
+  <summary>Number of serialized UKM entries when storing a UKM log.</summary>
+</histogram>
+
 <histogram name="UKM.InitSequence" enum="UmaInitSequence">
   <owner>holte@chromium.org</owner>
   <owner>rkaplow@chromium.org</owner>
@@ -71984,20 +72007,19 @@
   <summary>The status when loading UKM PersistedLogs from Prefs.</summary>
 </histogram>
 
-<histogram name="UKM.Sources.Dropped" enum="UkmSourceDroppedReason">
+<histogram name="UKM.Sources.Dropped" enum="UkmDataDroppedReason">
   <owner>holte@chromium.org</owner>
   <owner>rkaplow@chromium.org</owner>
   <summary>
-    Counters for the rate at which UKM Sources are dropped for various reasons.
+    Number of UKM sources that are dropped. Categorized by the cause of it being
+    dropped.
   </summary>
 </histogram>
 
 <histogram name="UKM.Sources.SerializedCount">
   <owner>holte@chromium.org</owner>
   <owner>rkaplow@chromium.org</owner>
-  <summary>
-    Counter for number of serialized UKM sources when storing a UKM log.
-  </summary>
+  <summary>Number of serialized UKM sources when storing a UKM log.</summary>
 </histogram>
 
 <histogram name="UKM.UnsentLogs.DroppedSize" units="bytes">
@@ -82105,6 +82127,11 @@
   <int value="1" label="Too many"/>
 </enum>
 
+<enum name="BooleanTranslate" type="int">
+  <int value="0" label="Not Translated"/>
+  <int value="1" label="Translated"/>
+</enum>
+
 <enum name="BooleanUnknown" type="int">
   <int value="0" label="Known"/>
   <int value="1" label="Unknown"/>
@@ -110887,10 +110914,10 @@
   <int value="36" label="Tap unconfirmed"/>
 </enum>
 
-<enum name="UkmSourceDroppedReason" type="int">
+<enum name="UkmDataDroppedReason" type="int">
   <int value="0" label="Not dropped"/>
   <int value="1" label="Recording disabled"/>
-  <int value="2" label="Max sources hit"/>
+  <int value="2" label="Max hit"/>
 </enum>
 
 <enum name="UmaCleanExitConsistency" type="int">
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py
index 7b43df32..c543ecf3 100644
--- a/tools/perf/benchmarks/blink_perf.py
+++ b/tools/perf/benchmarks/blink_perf.py
@@ -13,8 +13,10 @@
 from telemetry.page import shared_page_state
 from telemetry import story
 from telemetry.value import list_of_scalar_values
+from telemetry.value import scalar
 
 from benchmarks import pywebsocket_server
+from measurements import timeline_controller
 from page_sets import webgl_supported_shared_state
 
 
@@ -119,6 +121,48 @@
     print log
 
 
+# TODO(wangxianzhu): Convert the paint benchmarks to use the new blink_perf
+# tracing once it's ready.
+class _BlinkPerfPaintMeasurement(_BlinkPerfMeasurement):
+  """Also collects prePaint and paint timing from traces."""
+
+  def __init__(self):
+    super(_BlinkPerfPaintMeasurement, self).__init__()
+    self._controller = None
+
+  def WillNavigateToPage(self, page, tab):
+    super(_BlinkPerfPaintMeasurement, self).WillNavigateToPage(page, tab)
+    self._controller = timeline_controller.TimelineController()
+    self._controller.trace_categories = 'blink,blink.console'
+    self._controller.SetUp(page, tab)
+    self._controller.Start(tab)
+
+  def DidRunPage(self, platform):
+    if self._controller:
+      self._controller.CleanUp(platform)
+
+  def ValidateAndMeasurePage(self, page, tab, results):
+    super(_BlinkPerfPaintMeasurement, self).ValidateAndMeasurePage(
+        page, tab, results)
+    self._controller.Stop(tab, results)
+    renderer = self._controller.model.GetRendererThreadFromTabId(tab.id)
+    # The marker marks the beginning and ending of the measured runs.
+    marker = next(event for event in renderer.async_slices
+                  if event.name == 'blink_perf'
+                  and event.category == 'blink.console')
+    assert marker
+
+    for event in renderer.all_slices:
+      if event.start < marker.start or event.end > marker.end:
+        continue
+      if event.name == 'FrameView::prePaint':
+        results.AddValue(
+            scalar.ScalarValue(page, 'prePaint', 'ms', event.duration))
+      if event.name == 'FrameView::paintTree':
+        results.AddValue(
+            scalar.ScalarValue(page, 'paint', 'ms', event.duration))
+
+
 class _BlinkPerfBenchmark(perf_benchmark.PerfBenchmark):
   test = _BlinkPerfMeasurement
 
@@ -210,6 +254,7 @@
 
 
 class BlinkPerfPaint(_BlinkPerfBenchmark):
+  test = _BlinkPerfPaintMeasurement
   tag = 'paint'
   subdir = 'Paint'
 
diff --git a/ui/arc/notification/arc_custom_notification_view.cc b/ui/arc/notification/arc_custom_notification_view.cc
index 1d150cb..5367000a 100644
--- a/ui/arc/notification/arc_custom_notification_view.cc
+++ b/ui/arc/notification/arc_custom_notification_view.cc
@@ -173,13 +173,17 @@
   void RequestFocusOnCloseButton() override {
     if (owner_->close_button_)
       owner_->close_button_->RequestFocus();
-    owner_->UpdateControlButtonsVisiblity();
+    owner_->UpdateControlButtonsVisibility();
   }
 
   bool IsPinned() const override {
     return owner_->item_->pinned();
   }
 
+  void UpdateControlButtonsVisibility() override {
+    owner_->UpdateControlButtonsVisibility();
+  }
+
  private:
   ArcCustomNotificationView* const owner_;
 
@@ -194,12 +198,12 @@
 
   void OnFocus() override {
     message_center::PaddedButton::OnFocus();
-    owner_->UpdateControlButtonsVisiblity();
+    owner_->UpdateControlButtonsVisibility();
   }
 
   void OnBlur() override {
     message_center::PaddedButton::OnBlur();
-    owner_->UpdateControlButtonsVisiblity();
+    owner_->UpdateControlButtonsVisibility();
   }
 
  private:
@@ -331,7 +335,7 @@
   SetPreferredSize(preferred_size);
 }
 
-void ArcCustomNotificationView::UpdateControlButtonsVisiblity() {
+void ArcCustomNotificationView::UpdateControlButtonsVisibility() {
   if (!surface_ || !floating_control_buttons_widget_)
     return;
 
@@ -451,7 +455,7 @@
   control_buttons_bounds.set_width(buttons_width);
   floating_control_buttons_widget_->SetBounds(control_buttons_bounds);
 
-  UpdateControlButtonsVisiblity();
+  UpdateControlButtonsVisibility();
 
   ash::wm::SnapWindowToPixelBoundary(surface_->window());
 }
@@ -484,11 +488,11 @@
 }
 
 void ArcCustomNotificationView::OnMouseEntered(const ui::MouseEvent&) {
-  UpdateControlButtonsVisiblity();
+  UpdateControlButtonsVisibility();
 }
 
 void ArcCustomNotificationView::OnMouseExited(const ui::MouseEvent&) {
-  UpdateControlButtonsVisiblity();
+  UpdateControlButtonsVisibility();
 }
 
 void ArcCustomNotificationView::OnFocus() {
diff --git a/ui/arc/notification/arc_custom_notification_view.h b/ui/arc/notification/arc_custom_notification_view.h
index 8461ff2..19864fa7 100644
--- a/ui/arc/notification/arc_custom_notification_view.h
+++ b/ui/arc/notification/arc_custom_notification_view.h
@@ -51,7 +51,7 @@
   void CreateFloatingControlButtons();
   void SetSurface(exo::NotificationSurface* surface);
   void UpdatePreferredSize();
-  void UpdateControlButtonsVisiblity();
+  void UpdateControlButtonsVisibility();
   void UpdatePinnedState();
   void UpdateSnapshot();
   void AttachSurface();
diff --git a/ui/compositor/test/in_process_context_factory.cc b/ui/compositor/test/in_process_context_factory.cc
index 0039960..aecb9b79 100644
--- a/ui/compositor/test/in_process_context_factory.cc
+++ b/ui/compositor/test/in_process_context_factory.cc
@@ -72,6 +72,7 @@
   void BindFramebuffer() override {
     context_provider()->ContextGL()->BindFramebuffer(GL_FRAMEBUFFER, 0);
   }
+  void SetDrawRectangle(const gfx::Rect& rect) override {}
   void Reshape(const gfx::Size& size,
                float device_scale_factor,
                const gfx::ColorSpace& color_space,
diff --git a/ui/gl/gl_angle_util_win.cc b/ui/gl/gl_angle_util_win.cc
index 4a2b37c..6bd8faab0 100644
--- a/ui/gl/gl_angle_util_win.cc
+++ b/ui/gl/gl_angle_util_win.cc
@@ -82,4 +82,54 @@
   return d3d9_device;
 }
 
+base::win::ScopedComPtr<IDCompositionDevice2> QueryDirectCompositionDevice(
+    base::win::ScopedComPtr<ID3D11Device> d3d11_device) {
+  // Each D3D11 device will have a DirectComposition device stored in its
+  // private data under this GUID.
+  // {CF81D85A-8D30-4769-8509-B9D73898D870}
+  static const GUID kDirectCompositionGUID = {
+      0xcf81d85a,
+      0x8d30,
+      0x4769,
+      {0x85, 0x9, 0xb9, 0xd7, 0x38, 0x98, 0xd8, 0x70}};
+
+  base::win::ScopedComPtr<IDCompositionDevice2> dcomp_device;
+  if (!d3d11_device)
+    return dcomp_device;
+
+  UINT data_size = sizeof(dcomp_device.get());
+  HRESULT hr = d3d11_device->GetPrivateData(kDirectCompositionGUID, &data_size,
+                                            dcomp_device.ReceiveVoid());
+  if (SUCCEEDED(hr) && dcomp_device)
+    return dcomp_device;
+
+  // Allocate a new DirectComposition device if none currently exists.
+  HMODULE dcomp_module = ::GetModuleHandle(L"dcomp.dll");
+  if (!dcomp_module)
+    return dcomp_device;
+
+  using PFN_DCOMPOSITION_CREATE_DEVICE2 = HRESULT(WINAPI*)(
+      IUnknown * renderingDevice, REFIID iid, void** dcompositionDevice);
+  PFN_DCOMPOSITION_CREATE_DEVICE2 create_device_function =
+      reinterpret_cast<PFN_DCOMPOSITION_CREATE_DEVICE2>(
+          ::GetProcAddress(dcomp_module, "DCompositionCreateDevice2"));
+  if (!create_device_function)
+    return dcomp_device;
+
+  base::win::ScopedComPtr<IDXGIDevice> dxgi_device;
+  d3d11_device.QueryInterface(dxgi_device.Receive());
+  base::win::ScopedComPtr<IDCompositionDesktopDevice> desktop_device;
+  hr = create_device_function(dxgi_device.get(),
+                              IID_PPV_ARGS(desktop_device.Receive()));
+  if (FAILED(hr))
+    return dcomp_device;
+
+  hr = desktop_device.QueryInterface(dcomp_device.Receive());
+  CHECK(SUCCEEDED(hr));
+  d3d11_device->SetPrivateDataInterface(kDirectCompositionGUID,
+                                        dcomp_device.get());
+
+  return dcomp_device;
+}
+
 }  // namespace gl
diff --git a/ui/gl/gl_angle_util_win.h b/ui/gl/gl_angle_util_win.h
index 6f08f913..b0a4a80 100644
--- a/ui/gl/gl_angle_util_win.h
+++ b/ui/gl/gl_angle_util_win.h
@@ -7,6 +7,7 @@
 
 #include <d3d11.h>
 #include <d3d9.h>
+#include <dcomp.h>
 
 #include "base/win/scoped_comptr.h"
 #include "ui/gl/gl_export.h"
@@ -18,6 +19,12 @@
 GL_EXPORT base::win::ScopedComPtr<IDirect3DDevice9>
 QueryD3D9DeviceObjectFromANGLE();
 
+// Query the DirectComposition device associated with a D3D11 device. May
+// create a new one if none exists.
+GL_EXPORT base::win::ScopedComPtr<IDCompositionDevice2>
+QueryDirectCompositionDevice(
+    base::win::ScopedComPtr<ID3D11Device> d3d11_device);
+
 }  // namespace gl
 
 #endif  // UI_GL_GL_ANGLE_UTIL_WIN_H_
diff --git a/ui/gl/gl_surface.cc b/ui/gl/gl_surface.cc
index 11f4ec2..c0ac7f0 100644
--- a/ui/gl/gl_surface.cc
+++ b/ui/gl/gl_surface.cc
@@ -168,6 +168,14 @@
   return false;
 }
 
+bool GLSurface::SupportsSetDrawRectangle() const {
+  return false;
+}
+
+bool GLSurface::SetDrawRectangle(const gfx::Rect& rect) {
+  return false;
+}
+
 GLSurface* GLSurface::GetCurrent() {
   return current_surface_.Pointer()->Get();
 }
@@ -349,6 +357,14 @@
   return surface_->BuffersFlipped();
 }
 
+bool GLSurfaceAdapter::SupportsSetDrawRectangle() const {
+  return surface_->SupportsSetDrawRectangle();
+}
+
+bool GLSurfaceAdapter::SetDrawRectangle(const gfx::Rect& rect) {
+  return surface_->SetDrawRectangle(rect);
+}
+
 void GLSurfaceAdapter::OnSetSwapInterval(int interval) {
   surface_->OnSetSwapInterval(interval);
 }
diff --git a/ui/gl/gl_surface.h b/ui/gl/gl_surface.h
index fec580ba..1dee059 100644
--- a/ui/gl/gl_surface.h
+++ b/ui/gl/gl_surface.h
@@ -205,6 +205,11 @@
   // the next buffer may be 2 frames old.
   virtual bool BuffersFlipped() const;
 
+  virtual bool SupportsSetDrawRectangle() const;
+
+  // Set the rectangle that will be drawn into on the surface.
+  virtual bool SetDrawRectangle(const gfx::Rect& rect);
+
   static GLSurface* GetCurrent();
 
   // Called when the swap interval for the associated context changes.
@@ -275,6 +280,8 @@
   bool IsSurfaceless() const override;
   bool FlipsVertically() const override;
   bool BuffersFlipped() const override;
+  bool SupportsSetDrawRectangle() const override;
+  bool SetDrawRectangle(const gfx::Rect& rect) override;
   void OnSetSwapInterval(int interval) override;
 
   GLSurface* surface() const { return surface_.get(); }
diff --git a/ui/message_center/views/custom_notification_content_view_delegate.h b/ui/message_center/views/custom_notification_content_view_delegate.h
index fbbcc68..c61e8b9b 100644
--- a/ui/message_center/views/custom_notification_content_view_delegate.h
+++ b/ui/message_center/views/custom_notification_content_view_delegate.h
@@ -22,6 +22,7 @@
   virtual bool IsCloseButtonFocused() const = 0;
   virtual void RequestFocusOnCloseButton() = 0;
   virtual bool IsPinned() const = 0;
+  virtual void UpdateControlButtonsVisibility() = 0;
 };
 
 // The struct to hold a view and CustomNotificationContentViewDelegate
diff --git a/ui/message_center/views/custom_notification_view.cc b/ui/message_center/views/custom_notification_view.cc
index 6896796..e3787fef 100644
--- a/ui/message_center/views/custom_notification_view.cc
+++ b/ui/message_center/views/custom_notification_view.cc
@@ -78,6 +78,11 @@
   return contents_view_delegate_->IsPinned();
 }
 
+void CustomNotificationView::UpdateControlButtonsVisibility() {
+  if (contents_view_delegate_)
+    contents_view_delegate_->UpdateControlButtonsVisibility();
+}
+
 gfx::Size CustomNotificationView::GetPreferredSize() const {
   const gfx::Insets insets = GetInsets();
   const int contents_width = kNotificationWidth - insets.width();
diff --git a/ui/message_center/views/custom_notification_view.h b/ui/message_center/views/custom_notification_view.h
index 0700010..78cdbee 100644
--- a/ui/message_center/views/custom_notification_view.h
+++ b/ui/message_center/views/custom_notification_view.h
@@ -33,6 +33,7 @@
   bool IsCloseButtonFocused() const override;
   void RequestFocusOnCloseButton() override;
   bool IsPinned() const override;
+  void UpdateControlButtonsVisibility() override;
 
   // Overridden from views::View:
   gfx::Size GetPreferredSize() const override;
diff --git a/ui/message_center/views/custom_notification_view_unittest.cc b/ui/message_center/views/custom_notification_view_unittest.cc
index c90b1ac..35462b4 100644
--- a/ui/message_center/views/custom_notification_view_unittest.cc
+++ b/ui/message_center/views/custom_notification_view_unittest.cc
@@ -89,6 +89,7 @@
   bool IsCloseButtonFocused() const override { return false; }
   void RequestFocusOnCloseButton() override {}
   bool IsPinned() const override { return false; }
+  void UpdateControlButtonsVisibility() override {}
 };
 
 class TestNotificationDelegate : public NotificationDelegate {
diff --git a/ui/message_center/views/message_center_bubble.cc b/ui/message_center/views/message_center_bubble.cc
index e340ca3..3045bfd2 100644
--- a/ui/message_center/views/message_center_bubble.cc
+++ b/ui/message_center/views/message_center_bubble.cc
@@ -97,6 +97,7 @@
   message_center_view_ = new MessageCenterView(
       message_center(), tray(), max_height(), initially_settings_visible_);
   bubble_view()->AddChildView(new ContentsView(this, message_center_view_));
+  message_center_view_->Init();
   // Resize the content of the bubble view to the given bubble size. This is
   // necessary in case of the bubble border forcing a bigger size then the
   // |new_bubble_view| actually wants. See crbug.com/169390.
diff --git a/ui/message_center/views/message_center_view.cc b/ui/message_center/views/message_center_view.cc
index 3b0062e..375d42b 100644
--- a/ui/message_center/views/message_center_view.cc
+++ b/ui/message_center/views/message_center_view.cc
@@ -77,7 +77,8 @@
       is_locked_(message_center_->IsLockedState()),
       mode_((!initially_settings_visible || is_locked_) ? Mode::BUTTONS_ONLY
                                                         : Mode::SETTINGS),
-      context_menu_controller_(new MessageViewContextMenuController(this)) {
+      context_menu_controller_(new MessageViewContextMenuController(this)),
+      focus_manager_(nullptr) {
   message_center_->AddObserver(this);
   set_notify_enter_exit_on_child(true);
   set_background(views::Background::CreateSolidBackground(
@@ -133,6 +134,15 @@
 
   if (!is_closing_)
     message_center_->RemoveObserver(this);
+
+  if (focus_manager_)
+    focus_manager_->RemoveFocusChangeListener(this);
+}
+
+void MessageCenterView::Init() {
+  focus_manager_ = GetFocusManager();
+  if (focus_manager_)
+    focus_manager_->AddFocusChangeListener(this);
 }
 
 void MessageCenterView::SetNotifications(
@@ -204,6 +214,18 @@
     message_center_->AddObserver(this);
 }
 
+void MessageCenterView::OnDidChangeFocus(views::View* before,
+                                         views::View* now) {
+  if (message_list_view_ && (message_list_view_->Contains(before) ||
+                             message_list_view_->Contains(now))) {
+    // Focus state of a children of message view center is changed.
+    for (auto pair : notification_views_) {
+      if (pair.second->Contains(before) || pair.second->Contains(now))
+        pair.second->UpdateControlButtonsVisibility();
+    }
+  }
+}
+
 void MessageCenterView::Layout() {
   if (is_closing_)
     return;
diff --git a/ui/message_center/views/message_center_view.h b/ui/message_center/views/message_center_view.h
index da206b0..60f9d73 100644
--- a/ui/message_center/views/message_center_view.h
+++ b/ui/message_center/views/message_center_view.h
@@ -15,6 +15,7 @@
 #include "ui/message_center/views/message_center_controller.h"
 #include "ui/message_center/views/message_list_view.h"
 #include "ui/message_center/views/message_view.h"
+#include "ui/views/focus/focus_manager.h"
 #include "ui/views/view.h"
 
 namespace gfx {
@@ -40,7 +41,8 @@
       public MessageCenterObserver,
       public MessageCenterController,
       public MessageListView::Observer,
-      public gfx::AnimationDelegate {
+      public gfx::AnimationDelegate,
+      public views::FocusChangeListener {
  public:
   MessageCenterView(MessageCenter* message_center,
                     MessageCenterTray* tray,
@@ -48,6 +50,8 @@
                     bool initially_settings_visible);
   ~MessageCenterView() override;
 
+  void Init();
+
   void SetNotifications(const NotificationList::Notifications& notifications);
 
   void ClearAllClosableNotifications();
@@ -61,6 +65,10 @@
 
   void SetIsClosing(bool is_closing);
 
+  // Overridden from views::FocusChangeListener
+  void OnWillChangeFocus(views::View* before, views::View* now) override {}
+  void OnDidChangeFocus(views::View* before, views::View* now) override;
+
  protected:
   // Potentially sets the reposition target, and then returns whether or not it
   // was was set.
@@ -155,6 +163,8 @@
 
   std::unique_ptr<MessageViewContextMenuController> context_menu_controller_;
 
+  views::FocusManager* focus_manager_ = nullptr;
+
   DISALLOW_COPY_AND_ASSIGN(MessageCenterView);
 };
 
diff --git a/ui/message_center/views/message_view.h b/ui/message_center/views/message_view.h
index c0f8282..b165ae7 100644
--- a/ui/message_center/views/message_view.h
+++ b/ui/message_center/views/message_view.h
@@ -53,6 +53,7 @@
   virtual bool IsCloseButtonFocused() const = 0;
   virtual void RequestFocusOnCloseButton() = 0;
   virtual bool IsPinned() const = 0;
+  virtual void UpdateControlButtonsVisibility() = 0;
 
   // Overridden from views::View:
   void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
diff --git a/ui/message_center/views/notification_view.cc b/ui/message_center/views/notification_view.cc
index 966fe19f..da750d9 100644
--- a/ui/message_center/views/notification_view.cc
+++ b/ui/message_center/views/notification_view.cc
@@ -345,6 +345,16 @@
   return views::GetNativeHandCursor();
 }
 
+void NotificationView::OnMouseEntered(const ui::MouseEvent& event) {
+  MessageView::OnMouseEntered(event);
+  UpdateControlButtonsVisibility();
+}
+
+void NotificationView::OnMouseExited(const ui::MouseEvent& event) {
+  MessageView::OnMouseExited(event);
+  UpdateControlButtonsVisibility();
+}
+
 void NotificationView::UpdateWithNotification(
     const Notification& notification) {
   MessageView::UpdateWithNotification(notification);
@@ -525,6 +535,7 @@
     settings_button_view_ = settings;
     AddChildView(settings_button_view_);
   }
+  UpdateControlButtonsVisibility();
 }
 
 void NotificationView::CreateOrUpdateProgressBarView(
@@ -689,11 +700,29 @@
         IDS_MESSAGE_CENTER_CLOSE_NOTIFICATION_BUTTON_TOOLTIP));
     close_button_->set_owned_by_client();
     AddChildView(close_button_.get());
+    UpdateControlButtonsVisibility();
   } else if (notification.pinned() && close_button_) {
     close_button_.reset();
   }
 }
 
+void NotificationView::UpdateControlButtonsVisibility() {
+  const bool target_visibility =
+      IsMouseHovered() || HasFocus() ||
+      (close_button_ && close_button_->HasFocus()) ||
+      (settings_button_view_ && settings_button_view_->HasFocus());
+
+  if (close_button_) {
+    if (target_visibility != close_button_->visible())
+      close_button_->SetVisible(target_visibility);
+  }
+
+  if (settings_button_view_) {
+    if (target_visibility != settings_button_view_->visible())
+      settings_button_view_->SetVisible(target_visibility);
+  }
+}
+
 int NotificationView::GetMessageLineLimit(int title_lines, int width) const {
   // Image notifications require that the image must be kept flush against
   // their icons, but we can allow more text if no image.
diff --git a/ui/message_center/views/notification_view.h b/ui/message_center/views/notification_view.h
index 647dd57..127b5a9 100644
--- a/ui/message_center/views/notification_view.h
+++ b/ui/message_center/views/notification_view.h
@@ -46,6 +46,8 @@
   void OnFocus() override;
   void ScrollRectToVisible(const gfx::Rect& rect) override;
   gfx::NativeCursor GetCursor(const ui::MouseEvent& event) override;
+  void OnMouseEntered(const ui::MouseEvent& event) override;
+  void OnMouseExited(const ui::MouseEvent& event) override;
 
   // Overridden from MessageView:
   void UpdateWithNotification(const Notification& notification) override;
@@ -53,6 +55,7 @@
   bool IsCloseButtonFocused() const override;
   void RequestFocusOnCloseButton() override;
   bool IsPinned() const override;
+  void UpdateControlButtonsVisibility() override;
 
  protected:
   views::ImageButton* close_button() { return close_button_.get(); }
diff --git a/ui/message_center/views/padded_button.cc b/ui/message_center/views/padded_button.cc
index a0c6a44..619dcd5 100644
--- a/ui/message_center/views/padded_button.cc
+++ b/ui/message_center/views/padded_button.cc
@@ -7,6 +7,9 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/gfx/canvas.h"
 #include "ui/message_center/message_center_style.h"
+#include "ui/views/animation/flood_fill_ink_drop_ripple.h"
+#include "ui/views/animation/ink_drop_impl.h"
+#include "ui/views/background.h"
 #include "ui/views/border.h"
 #include "ui/views/controls/button/image_button.h"
 #include "ui/views/painter.h"
@@ -19,12 +22,28 @@
   SetFocusPainter(views::Painter::CreateSolidFocusPainter(
       kFocusBorderColor,
       gfx::Insets(1, 2, 2, 2)));
+  set_background(views::Background::CreateSolidBackground(
+      SkColorSetA(SK_ColorWHITE, 0.9 * 0xff)));
   SetBorder(
       views::CreateEmptyBorder(gfx::Insets(kControlButtonPaddingFromBorder)));
   set_animate_on_state_change(false);
+
+  SetInkDropMode(InkDropMode::ON);
+  set_ink_drop_base_color(SkColorSetA(SK_ColorBLACK, 0.6 * 0xff));
 }
 
-PaddedButton::~PaddedButton() {
+std::unique_ptr<views::InkDrop> PaddedButton::CreateInkDrop() {
+  auto ink_drop = CreateDefaultInkDropImpl();
+  ink_drop->SetShowHighlightOnHover(false);
+  ink_drop->SetShowHighlightOnFocus(false);
+  return std::move(ink_drop);
+}
+
+std::unique_ptr<views::InkDropRipple> PaddedButton::CreateInkDropRipple()
+    const {
+  return base::MakeUnique<views::FloodFillInkDropRipple>(
+      size(), GetInkDropCenterBasedOnLastEvent(),
+      SkColorSetA(SK_ColorBLACK, 0.6 * 255), ink_drop_visible_opacity());
 }
 
 }  // namespace message_center
diff --git a/ui/message_center/views/padded_button.h b/ui/message_center/views/padded_button.h
index 1624579..2d9c6b0a 100644
--- a/ui/message_center/views/padded_button.h
+++ b/ui/message_center/views/padded_button.h
@@ -8,6 +8,8 @@
 #include "base/compiler_specific.h"
 #include "base/macros.h"
 #include "ui/message_center/message_center_export.h"
+#include "ui/views/animation/ink_drop.h"
+#include "ui/views/animation/ink_drop_ripple.h"
 #include "ui/views/controls/button/image_button.h"
 
 namespace message_center {
@@ -22,7 +24,11 @@
 class MESSAGE_CENTER_EXPORT PaddedButton : public views::ImageButton {
  public:
   PaddedButton(views::ButtonListener* listener);
-  ~PaddedButton() override;
+  ~PaddedButton() override = default;
+
+  // Overridden from InkDropHostView
+  std::unique_ptr<views::InkDrop> CreateInkDrop() override;
+  std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override;
 
  private:
   DISALLOW_COPY_AND_ASSIGN(PaddedButton);
diff --git a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
index c793f8d..246aa2b 100644
--- a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
+++ b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.html
@@ -33,11 +33,11 @@
         border-bottom: 1px solid var(--divider-color);
         display: flex;
         min-height: 52px;
+        outline: none;
       }
 
       :host ::content .title {
         font-size: 123.07%; /* (16px / 13px) * 100 */
-        outline: none;
       }
 
       #close {
@@ -95,7 +95,7 @@
         border-top: 1px solid var(--divider-color);
       }
     </style>
-    <div class="title-container">
+    <div class="title-container" tabindex="-1">
       <content select=".title"></content>
       <paper-icon-button icon="cr:clear" on-tap="cancel" id="close"
           aria-label$="[[closeText]]">
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 3e29f9f..d15ed9b 100644
--- a/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js
+++ b/ui/webui/resources/cr_elements/cr_dialog/cr_dialog.js
@@ -41,13 +41,6 @@
     }.bind(this));
   },
 
-  /** @override */
-  attached: function() {
-    var title = this.getContentChildren('[select=".title"]');
-    if (title.length)
-      title[0].tabIndex = -1;
-  },
-
   cancel: function() {
     this.fire('cancel');
     HTMLDialogElement.prototype.close.call(this, '');
diff --git a/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html b/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html
index d37690a..dfca072 100644
--- a/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html
+++ b/ui/webui/resources/cr_elements/cr_drawer/cr_drawer.html
@@ -1,7 +1,7 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
 <link rel="import" href="chrome://resources/cr_elements/shared_vars_css.html">
 
-<dom-module name="cr-drawer">
+<dom-module id="cr-drawer">
   <template>
     <style>
       :host {
diff --git a/ui/webui/resources/cr_elements/cr_slider/cr_slider.html b/ui/webui/resources/cr_elements/cr_slider/cr_slider.html
index c398fc5e..890950b 100644
--- a/ui/webui/resources/cr_elements/cr_slider/cr_slider.html
+++ b/ui/webui/resources/cr_elements/cr_slider/cr_slider.html
@@ -2,7 +2,7 @@
 <link rel="import" href="chrome://resources/html/polymer.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-slider/paper-slider.html">
 
-<dom-module is="cr-slider">
+<dom-module id="cr-slider">
   <template>
     <style>
       div.outer {
diff --git a/ui/webui/resources/cr_elements/policy/README.md b/ui/webui/resources/cr_elements/policy/README.md
new file mode 100644
index 0000000..673fd24
--- /dev/null
+++ b/ui/webui/resources/cr_elements/policy/README.md
@@ -0,0 +1,42 @@
+# Policy indicators
+
+Settings that can't be controlled by the current user often show an icon and a
+tooltip explaining why. This happens when a setting is:
+
+* enforced by user policy, or different from a policy's "recommended" value
+* overridden by an extension
+* or (on Chrome OS):
+    * enforced/recommended by device policy (for enrolled devices)
+    * set by the device owner (for non-enrolled devices)
+    * controlled by the primary user (for multiple profile sessions)
+
+## Indicator UI
+
+The badge icons are sourced from [cr_elements/icons.html] by default.
+
+Indicators show a tooltip with explanatory text on hover if `CrPolicyStrings`
+is set; see [settings_ui.js] for an example from MD Settings.
+
+## Using an indicator
+
+Elements like `<cr-policy-pref-indicator>` and `<cr-policy-network-indicator>`
+are provided to be reused in WebUI pages:
+
+    <cr-policy-pref-indicator pref="[[pref]]"></cr-policy-pref-indicator>
+
+Example: [settings-checkbox].
+
+For one-off or composed elements, `CrPolicyIndicatorBehavior` provides some
+configurable properties and calculates dependent properties, such as the
+tooltip, icon, and visibility of the indicator.
+
+Example: [cr_policy_pref_indicator.js] overrides `indicatorType` and
+`indicatorTooltip`. [cr_policy_pref_indicator.html] displays the computed
+properties from `CrPolicyIndicatorBehavior`.
+
+
+[cr_elements/icons.html]: ../icons.html
+[settings_ui.js]: /chrome/browser/resources/settings/settings_ui/settings_ui.js
+[settings-checkbox]: /chrome/browser/resources/settings/controls/settings_checkbox.html
+[cr_policy_pref_indicator.js]: cr_policy_pref_indicator.js
+[cr_policy_pref_indicator.html]: cr_policy_pref_indicator.html
diff --git a/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp b/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp
index a654cab..9f82600b 100644
--- a/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp
+++ b/ui/webui/resources/cr_elements/policy/compiled_resources2.gyp
@@ -23,7 +23,6 @@
       'dependencies': [
         '<(EXTERNS_GYP):settings_private',
         'cr_policy_indicator_behavior',
-        'cr_policy_pref_behavior',
       ],
       'includes': ['../../../../../third_party/closure_compiler/compile_js2.gypi'],
     },
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_indicator.css b/ui/webui/resources/cr_elements/policy/cr_policy_indicator.css
deleted file mode 100644
index 26b4fb2..0000000
--- a/ui/webui/resources/cr_elements/policy/cr_policy_indicator.css
+++ /dev/null
@@ -1,9 +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. */
-
-/* Note: we use display: block here to avoid positioning issues related to
- * the use of overflow: hidden. */
-:host {
-  @apply(--cr-policy-indicator);
-}
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js b/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js
index fb6eb7c..6ebec5e 100644
--- a/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js
+++ b/ui/webui/resources/cr_elements/policy/cr_policy_indicator_behavior.js
@@ -4,6 +4,8 @@
 
 /**
  * @fileoverview Behavior for policy controlled indicators.
+ * TODO(michaelpg): Since extensions can also control settings and be indicated,
+ * rework the "policy" naming scheme throughout this directory.
  */
 
 /**
@@ -32,12 +34,51 @@
 
 /** @polymerBehavior */
 var CrPolicyIndicatorBehavior = {
+  // Properties exposed to all policy indicators.
+  properties: {
+    /**
+     * Which indicator type to show (or NONE).
+     * @type {CrPolicyIndicatorType}
+     */
+    indicatorType: {
+      type: String,
+      value: CrPolicyIndicatorType.NONE,
+    },
+
+    /**
+     * The name associated with the policy source. See
+     * chrome.settingsPrivate.PrefObject.controlledByName.
+     */
+    indicatorSourceName: {
+      type: String,
+      value: '',
+    },
+
+    // Computed properties based on indicatorType and indicatorSourceName.
+    // Override to provide different values.
+
+    indicatorVisible: {
+      type: Boolean,
+      computed: 'getIndicatorVisible_(indicatorType)',
+    },
+
+    indicatorIcon: {
+      type: String,
+      computed: 'getIndicatorIcon_(indicatorType)',
+    },
+
+    indicatorTooltip: {
+      type: String,
+      computed: 'getIndicatorTooltip(indicatorType, indicatorSourceName)',
+    },
+  },
+
   /**
    * @param {CrPolicyIndicatorType} type
    * @return {boolean} True if the indicator should be shown.
    * @private
    */
-  isIndicatorVisible: function(type) {
+  getIndicatorVisible_: function(type) {
     return type != CrPolicyIndicatorType.NONE &&
         type != CrPolicyIndicatorType.EXTENSION;
   },
@@ -47,7 +88,7 @@
    * @return {string} The iron-icon icon name.
    * @private
    */
-  getPolicyIndicatorIcon: function(type) {
+  getIndicatorIcon_: function(type) {
     var icon = '';
     switch (type) {
       case CrPolicyIndicatorType.EXTENSION:
@@ -78,7 +119,7 @@
    *     value matches the recommended value.
    * @return {string} The tooltip text for |type|.
    */
-  getPolicyIndicatorTooltip: function(type, name, opt_matches) {
+  getIndicatorTooltip: function(type, name, opt_matches) {
     if (!CrPolicyStrings)
       return '';  // Tooltips may not be defined, e.g. in OOBE.
     switch (type) {
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_network_indicator.html b/ui/webui/resources/cr_elements/policy/cr_policy_network_indicator.html
index e7b0346..ded65ec7 100644
--- a/ui/webui/resources/cr_elements/policy/cr_policy_network_indicator.html
+++ b/ui/webui/resources/cr_elements/policy/cr_policy_network_indicator.html
@@ -4,21 +4,24 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-tooltip/paper-tooltip.html">
 <link rel="import" href="cr_policy_indicator_behavior.html">
 <link rel="import" href="cr_policy_network_behavior.html">
+<link rel="import" href="cr_policy_vars_css.html">
 
 <dom-module id="cr-policy-network-indicator">
-  <link rel="import" type="css" href="cr_policy_indicator.css">
   <style>
+    :host {
+      @apply(--cr-policy-indicator);
+    }
+
     paper-tooltip {
       --paper-tooltip: var(--cr-policy-tooltip);
     }
   </style>
   <template>
-    <iron-icon id="indicator" tabindex=0
-        hidden$="[[!isIndicatorVisible(indicatorType)]]"
-        icon="[[getPolicyIndicatorIcon(indicatorType)]]">
+    <iron-icon id="indicator" tabindex="0" hidden$="[[!indicatorVisible]]"
+        icon="[[indicatorIcon]]">
     </iron-icon>
     <paper-tooltip for="indicator" position="top" fit-to-visible-bounds>
-      [[getTooltip_(indicatorType)]]
+      [[indicatorTooltip]]
     </paper-tooltip>
   </template>
   <script src="cr_policy_network_indicator.js"></script>
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_network_indicator.js b/ui/webui/resources/cr_elements/policy/cr_policy_network_indicator.js
index 16dae611..6d9d7fe2 100644
--- a/ui/webui/resources/cr_elements/policy/cr_policy_network_indicator.js
+++ b/ui/webui/resources/cr_elements/policy/cr_policy_network_indicator.js
@@ -20,16 +20,16 @@
     property: {type: Object, observer: 'propertyChanged_'},
 
     /**
-     * Which indicator type to show (or NONE).
-     * @type {!CrPolicyIndicatorType}
-     */
-    indicatorType: {type: String, value: CrPolicyIndicatorType.NONE},
-
-    /**
      * Recommended value for non enforced properties.
      * @private {!CrOnc.NetworkPropertyType|undefined}
      */
     recommended_: Object,
+
+    /** @override */
+    indicatorTooltip: {
+      type: String,
+      computed: 'getNetworkIndicatorTooltip_(indicatorType)',
+    },
   },
 
   /**
@@ -74,7 +74,7 @@
    * @return {string} The tooltip text for |type|.
    * @private
    */
-  getTooltip_: function() {
+  getNetworkIndicatorTooltip_: function() {
     var matches;
     if (this.indicatorType == CrPolicyIndicatorType.RECOMMENDED &&
         this.property) {
@@ -83,6 +83,6 @@
         value = this.property[this.property.Effective];
       matches = value == this.recommended_;
     }
-    return this.getPolicyIndicatorTooltip(this.indicatorType, '', matches);
+    return this.getIndicatorTooltip(this.indicatorType, '', matches);
   }
 });
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_pref_behavior.js b/ui/webui/resources/cr_elements/policy/cr_policy_pref_behavior.js
index 0fd367c..ad393b9 100644
--- a/ui/webui/resources/cr_elements/policy/cr_policy_pref_behavior.js
+++ b/ui/webui/resources/cr_elements/policy/cr_policy_pref_behavior.js
@@ -9,35 +9,20 @@
 /** @polymerBehavior */
 var CrPolicyPrefBehavior = {
   /**
-   * @param {!chrome.settingsPrivate.PrefObject} pref
-   * @return {boolean} True if the pref is controlled by an enforced policy.
+   * @return {boolean} True if |this.pref| is controlled by an enforced policy.
    */
-  isPrefPolicyControlled: function(pref) {
-    return pref.enforcement == chrome.settingsPrivate.Enforcement.ENFORCED &&
-        pref.controlledBy != chrome.settingsPrivate.ControlledBy.EXTENSION;
+  isPrefPolicyControlled: function() {
+    return (
+        this.pref.enforcement == chrome.settingsPrivate.Enforcement.ENFORCED &&
+        this.pref.controlledBy !=
+            chrome.settingsPrivate.ControlledBy.EXTENSION);
   },
 
   /**
-   * @param {!chrome.settingsPrivate.ControlledBy|undefined} controlledBy
-   * @param {!chrome.settingsPrivate.Enforcement|undefined} enforcement
-   * @return {CrPolicyIndicatorType} The indicator type based on |controlledBy|
-   *     and |enforcement|.
+   * @return {boolean} True if |this.pref| has a recommended or enforced policy.
    */
-  getIndicatorType: function(controlledBy, enforcement) {
-    if (enforcement == chrome.settingsPrivate.Enforcement.RECOMMENDED)
-      return CrPolicyIndicatorType.RECOMMENDED;
-    if (enforcement == chrome.settingsPrivate.Enforcement.ENFORCED) {
-      switch (controlledBy) {
-        case chrome.settingsPrivate.ControlledBy.PRIMARY_USER:
-          return CrPolicyIndicatorType.PRIMARY_USER;
-        case chrome.settingsPrivate.ControlledBy.OWNER:
-          return CrPolicyIndicatorType.OWNER;
-        case chrome.settingsPrivate.ControlledBy.USER_POLICY:
-          return CrPolicyIndicatorType.USER_POLICY;
-        case chrome.settingsPrivate.ControlledBy.DEVICE_POLICY:
-          return CrPolicyIndicatorType.DEVICE_POLICY;
-      }
-    }
-    return CrPolicyIndicatorType.NONE;
+  hasPrefPolicyIndicator: function() {
+    return this.isPrefPolicyControlled() ||
+        this.pref.enforcement == chrome.settingsPrivate.Enforcement.RECOMMENDED;
   },
 };
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.html b/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.html
index a1cccce1..deb56836 100644
--- a/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.html
+++ b/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.html
@@ -3,14 +3,12 @@
 <link rel="import" href="chrome://resources/polymer/v1_0/iron-icon/iron-icon.html">
 <link rel="import" href="chrome://resources/polymer/v1_0/paper-tooltip/paper-tooltip.html">
 <link rel="import" href="cr_policy_indicator_behavior.html">
-<link rel="import" href="cr_policy_pref_behavior.html">
 <link rel="import" href="cr_policy_vars_css.html">
 
 <dom-module id="cr-policy-pref-indicator">
-  <link rel="import" type="css" href="cr_policy_indicator.css">
   <style>
     :host {
-      display: flex;  /* Position independantly from the line-height. */
+      @apply(--cr-policy-indicator);
     }
 
     paper-tooltip {
@@ -18,12 +16,11 @@
     }
   </style>
   <template>
-    <iron-icon id="indicator" tabindex=0 aria-describedby="tooltip"
-        hidden$="[[!isIndicatorVisible(indicatorType_)]]"
-        icon="[[getPolicyIndicatorIcon(indicatorType_)]]"></iron-icon>
+    <iron-icon id="indicator" tabindex="0" aria-describedby="tooltip"
+        hidden$="[[!indicatorVisible]]" icon="[[indicatorIcon]]"></iron-icon>
     <paper-tooltip id="tooltip" for="indicator" position="top"
         fit-to-visible-bounds>
-      [[getTooltip_(indicatorType_, pref.*)]]
+      [[indicatorTooltip]]
     </paper-tooltip>
   </template>
   <script src="cr_policy_pref_indicator.js"></script>
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.js b/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.js
index 37487ec..532b0763 100644
--- a/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.js
+++ b/ui/webui/resources/cr_elements/policy/cr_policy_pref_indicator.js
@@ -9,7 +9,7 @@
 Polymer({
   is: 'cr-policy-pref-indicator',
 
-  behaviors: [CrPolicyIndicatorBehavior, CrPolicyPrefBehavior],
+  behaviors: [CrPolicyIndicatorBehavior],
 
   properties: {
     /**
@@ -22,30 +22,53 @@
     /**
      * Which indicator type to show (or NONE).
      * @type {CrPolicyIndicatorType}
-     * @private
+     * @override
      */
-    indicatorType_: {
+    indicatorType: {
       type: String,
       value: CrPolicyIndicatorType.NONE,
-      computed: 'getIndicatorType(pref.controlledBy, pref.enforcement)',
+      computed: 'getIndicatorTypeForPref_(pref.controlledBy, pref.enforcement)',
+    },
+
+    /** @override */
+    indicatorTooltip: {
+      type: String,
+      computed: 'getIndicatorTooltipForPref_(indicatorType, pref.*)',
     },
   },
 
   /**
-   * @param {CrPolicyIndicatorType} type
-   * @return {string} The tooltip text for |type|.
-   * @private
+   * @param {!chrome.settingsPrivate.ControlledBy|undefined} controlledBy
+   * @param {!chrome.settingsPrivate.Enforcement|undefined} enforcement
+   * @return {CrPolicyIndicatorType} The indicator type based on |controlledBy|
+   *     and |enforcement|.
    */
-  getTooltip_: function(type) {
-    var matches = !!this.pref && this.pref.value == this.pref.recommendedValue;
-    return this.getPolicyIndicatorTooltip(
-        type, this.pref.controlledByName || '', matches);
+  getIndicatorTypeForPref_: function(controlledBy, enforcement) {
+    if (enforcement == chrome.settingsPrivate.Enforcement.RECOMMENDED)
+      return CrPolicyIndicatorType.RECOMMENDED;
+    if (enforcement == chrome.settingsPrivate.Enforcement.ENFORCED) {
+      switch (controlledBy) {
+        case chrome.settingsPrivate.ControlledBy.PRIMARY_USER:
+          return CrPolicyIndicatorType.PRIMARY_USER;
+        case chrome.settingsPrivate.ControlledBy.OWNER:
+          return CrPolicyIndicatorType.OWNER;
+        case chrome.settingsPrivate.ControlledBy.USER_POLICY:
+          return CrPolicyIndicatorType.USER_POLICY;
+        case chrome.settingsPrivate.ControlledBy.DEVICE_POLICY:
+          return CrPolicyIndicatorType.DEVICE_POLICY;
+      }
+    }
+    return CrPolicyIndicatorType.NONE;
   },
 
   /**
-   * @return {boolean} Whether the policy indicator is on. Useful for testing.
+   * @param {CrPolicyIndicatorType} indicatorType
+   * @return {string} The tooltip text for |indicatorType|.
+   * @private
    */
-  isActive: function() {
-    return this.isIndicatorVisible(this.indicatorType_);
+  getIndicatorTooltipForPref_: function(indicatorType) {
+    var matches = this.pref && this.pref.value == this.pref.recommendedValue;
+    return this.getIndicatorTooltip(
+        indicatorType, this.pref.controlledByName || '', matches);
   },
 });
diff --git a/ui/webui/resources/cr_elements/policy/cr_policy_vars_css.html b/ui/webui/resources/cr_elements/policy/cr_policy_vars_css.html
index e896203..c16dd650 100644
--- a/ui/webui/resources/cr_elements/policy/cr_policy_vars_css.html
+++ b/ui/webui/resources/cr_elements/policy/cr_policy_vars_css.html
@@ -3,7 +3,7 @@
   :root {
     --cr-policy-indicator: {
       @apply(--cr-icon-height-width);
-      display: block;
+      display: flex;  /* Position independently from the line-height. */
     };
 
     --cr-policy-tooltip: {
diff --git a/ui/webui/resources/cr_elements_resources.grdp b/ui/webui/resources/cr_elements_resources.grdp
index 34ecbfd..a643686 100644
--- a/ui/webui/resources/cr_elements_resources.grdp
+++ b/ui/webui/resources/cr_elements_resources.grdp
@@ -83,9 +83,6 @@
                type="chrome_html"
                preprocess="true" />
   </if>
-  <structure name="IDR_CR_ELEMENTS_CR_POLICY_INDICATOR_CSS"
-             file="../../webui/resources/cr_elements/policy/cr_policy_indicator.css"
-             type="chrome_html" />
   <structure name="IDR_CR_ELEMENTS_CR_POLICY_INDICATOR_BEHAVIOR_HTML"
              file="../../webui/resources/cr_elements/policy/cr_policy_indicator_behavior.html"
              type="chrome_html" />
diff --git a/ui/webui/resources/roboto/OWNERS b/ui/webui/resources/roboto/OWNERS
index 07a31a62..e7cc6135 100644
--- a/ui/webui/resources/roboto/OWNERS
+++ b/ui/webui/resources/roboto/OWNERS
@@ -1 +1,3 @@
 mathp@chromium.org
+
+# COMPONENT: UI>Browser